javaSE总结

1 java的历史

     1991-至今  詹姆斯-高斯林  SUN公司

     ORACLE 2009年

2 java的版本

     javaSE  java的标准桌面级开发

     javaEE  企业级web开发

     javaME  嵌入式开发

3 jdk的版本

   jdk1.0 - jdk11  每半年一个版本  每年的3月和9月

4 jdk 的安装和环境配置

  jdk--开发者必须安装

  jre--使用者安装

  java_home:jdk的安装目录

  javac:%java_home%/bin;  可以在任意目录结构中,进入jdk的bin目录,方便的找出javac.exe和java.exe

5 数据类型

         基本类型

         byte,short,int,long,char,float,double,boolean  

         引用类型

                           类,接口,数组,枚举

6 运算符

          算术运算符,关系运算符,逻辑运算符, 赋值运算符,位运算

7 流程语句

           单分支  if

           双分支  if else

          多分支

       if.. else if.. else     

       switch(){case..}  

8 循环语句

   while(条件){

                 循环体

                 变量更新

   }

  

   do{

   }while();

  

   for(初始值;范围值;变量更新){

          循环体

   }

9 方法

          无参无返回

          无参有返回

          有参无返回

          有参有返回

       形参:方法声明是时,形式上的参数,是一个局部变量

       实参:方法调用时,传递给方法实际有值的参数    

10 数组

        概念:一个开辟了连续的空间的线性数据结构    

        特点:查询快,增删慢

        可以添加任意的数据类型 

   数组的基本操作

        增  删  改  查 长度  判断  排序

       冒泡排序  插入排序,选择排序,快速排序          

11 面向对象编程  OOP  AOP(面向切面编程)      

       类:类是一类事务的模板,把很多具有相同功能的对象抽象出来,描述为一个类

       对象:每一个类的具体的实例

        类是对象的抽象化,对象是类的实例化   

  类的主要组成

      成员属性,成员方法,构造方法     

      成员属性:修饰符  数据类型  变量名;

      默认值

             整型:0

             浮点型:0.0

             布尔型:false

             引用类型:null

      变量的作用域

         局部变量:声明在方法中的变量,作用范围,只在本方法中

         成员变量

                   类变量(static),对象变量

      内存位置

               堆: 对象变量          

               方法区:类变量

      加载时机

                创建对象的时候,对象变量初始化 

                类被加载的时候,类变量就初始化

      份数

             对象变量,每一个对象各有一个

             类变量,被每一个对象所共享           

              

   成员方法

               修饰符  返回值  方法名(){

              

     }

 方法重载:overload

   1:同一个类

   2:方法名相同

   3:参数列表不同

     3.1 参数个数

     3.2 参数类型

     3.3 参数顺序

       和返回值无关      

  构造器

        修饰符  类名(){

   

    }  

         每一个类至少会有一个构造器,如果没有手动提供构造器,那么编译器会自动提供一个无参的构造器       

        构造器没有返回值    

        构造器也可以重载

       

    public Student(){

       this("张三");

    }            

    public Student(String name){

       this("李四",20);

    }  

    public Student(String name,int age){

   

    }

 this:代表当前对象的引用

   1:this可以调用成员属性

   2:this可以调用成员方法

   3:this可以调用构造方法

 static的用法

        修饰变量:代表类变量,被所有的对象共享

        修饰方法:代表类方法

        修饰类 :静态内部类

   细节

      成员方法中,既可以直接访问成员变量,也可以访问类变量        

      静态方法中,只可以访问类变量      

     成员方法既可以直接调用成员变量,也可以调用类方法            

     静态方法只可以调用类方法      

面向的3个特点

     封装,继承,多态

     封装:属性私有化,提供公开的get和set方法  隐藏细节,公开接口

                 属性的值是随着行为的变化而变化的  

  修饰符

    访问修饰符

     private:类可见性

     default:类可见,包可见性

     protected:类可见,包可见,不同包的子父类

     public:项目可见

    非访问修饰符      

    static,final,  synchronized,native,transient   

  继承:单继承,继承链  extends

          顶级父类:Object 

         子类可以继承父类的属性和方法,私有的不能继承

  

       修饰符 class 子类  extends 父类{

  

   }            

       优点:提高了代码的复用性

       缺点:高耦合,低内聚    

多态 :

         父类 变量名 = new 子类()  向上转型(父类的引用指向子类对象)

   多态的必要原则

     1:继承

     2:要有方法重写

     3:向上转型     

方法重写  override

  1:子父类之间  

  2:方法名,参数列表,返回值相同

super:代表父类的引用

  super.成员属性

  super.成员方法

  super(参数); 调用父类的构造函数

java中任何一个子类的构造方法都必须调用其父类的构造方法(包括隐示调用)

并且调用父类构造方法的语句必须是子类构造方法的第一条语句 

抽象类:就是为了被子类继承

  修饰符  abstract class 类名{

  } 

 特点

        1:可以有抽象方法

        2:可以有实现方法

        3:不可以创建对象

        4:利用多态通过向上转型,创建子类对象

接口 interface

   修饰符  class 类名 implements 接口名{

  

   }

 类与类

      继承关系,单继承,有继承链

 类与接口

     实现关系,多实现

 接口和接口

     继承关系,多继承

    

抽象类与接口的区别?

  变量

    抽象类有,接口没有

  常量

     抽象类有,接口有  public static final

  成员方法

     抽象类有,接口没有(jdk1.8之前没有) 

  抽象方法

     抽象类有,接口有 public abstract

  构造器

   抽象类有,接口没有 

  

 final的用法

  final修饰变量,表示常量,一旦被赋值,不可被修改 

  final修饰方法,表示这个方法不能被重写

  final修饰类,表示是一个最终类,不能被继承(所有的方法不能被重写)

 异常

  Throwable

  子类

    Exception  异常

    编译时异常

    运行时异常 RuntimeException

    Error     错误

   

 处理异常

   1:捕获异常

     try:尝试运行有可能会出错的代码

     catch:一旦代码出错,编译器生成一个异常对象,和catch中异常做匹配,匹配成功进入catch块,后面的代码正常执行

     finally:表示一定会执行,就算代码中有return,也会在return之前执行,除了虚拟机强制退出 System.exit(1);

   2:抛出异常  

     throws:在方法声明部分,抛出一个异常类,可以一次性声明多个异常

                                   有可能会抛出异常

     throw

                                  在方法体中,抛出一个异常对象,一定会抛出异常

   3:自定义异常

      1:继承Exception或者RuntimeException

      2:提供一个无参的,以及有参的构造函数      

     

      public class SexException extends Exception{

     

        public SexException(){

            super();

        }

        public SexException(String message){

            super(message);

        }

       

      }                       

常用类

  包装类

   Byte,Short,Integer,Long,Float,Double,Boolean,Character

 字符串 :String:是一个不可变的字符序列

    "abcde".substring(0,2) = "ab"

    "abc".charAt(0) = 'a'

    "abc".length() = 3

    "a,b,c".split(",") = ["a","b","c"]

    "abc".indexof("a") = 0

    "abaca".replaceAll("a","*") = "*b*c*";

字符串缓冲类

     StringBuffer:可变的字符序列  同步

     StringBuilder: 可变的字符序列  不同步

  

数学类:Math

   random()  0-1 之间的小数  包括0,不包括1

   max(int a,int b);

   min(int a,int b); 

   ceil(10.123) = 11

   floor(10.123) = 10

   pow(10,3) = 1000  次幂函数

 日期类:java.util.Date

   Date  date = new Date(); 获取当前系统时间

   getYear()+1900

   getMonth()+1

   getDate()

   getDay()

   getHours();

   getMinutes()

   getSeconds() 

   日期转为字符串

    date.toLocalString();

 日期转换类 DateFormat 子类  SimpleDateFormat

 DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 Date  date = new Date();

  //将日期转为字符串

  String s = date.format(date);

  //将字符串转为日期

  Date da = date.parse("1999-12-12");

 日历类 Calendar

  Calendar ca = Calendar.genInstance();

    ca.get(Calendar.YEAR); 获取年

    ca.get(Calendar.MONTH); 获取月

    ca.get(Calendar.DATE); 获取日

大整型 BigInteger

  BigInteger bg = new BigInteger(String.valueof(Long.MAX_VALUE))   

  bg = bg.add(new BigInteger("1"));  加法 给long的最大值+1

大浮点型  BigDecimal

  BigDecimal bd = new BigDecimal(String.valueof(Double.MAX_VALUE))   

  bd = bg.add(new BigDecimal("1"));  加法 给double的最大值+1

文件类:File

  File file = new File("d://工具//a.txt"); 

  file.createNewFile();

  renameTo()

  delete();

枚举:enum

 枚举里的变量默认的修饰符是public static final

 public enum Season(){

            春,夏,秋,冬

 } 

 Season.春

 Season[] son = Season.values();

 for(Season s:son){

    System.out.println(s.name)

 }

集合

   Collection

     List

       ArrayList:底层是数组,查询快,增删慢,不同步

       LinkedList:底层是链表,查询慢,增删快,不同步

       Vector:底层是数组,查询快,增删慢,同步

     Set

       HashSet:底层是哈希表(数组+链表)查询快,增删快,不同步

       LinkedHashSet:底层是哈希表+链表 查询快,增删快,不同步

       TreeSet:底层是树结构,排序

              2种排序方案

               1:自然排序,实现Comparable接口,重写comparTo()

               2:比较器排序,实现Comparator接口,重写compare()

   Map

      HashMap:底层是哈希表(数组+链表)查询快,增删快,不同步

      TreeMap:底层是树结构,排序

              2种排序方案

               1:自然排序,实现Comparable接口,重写comparTo()

               2:比较器排序,实现Comparator接口,重写compare()

      Hashtable:底层是哈希表(数组+链表)查询快,增删快,同步

  List接口:有序(添加顺序和迭代顺序一致)且重复     

  Set接口:无序且唯一

  List接口的遍历方式

    1:转数组  toArray

      ArrayList al = new ArrayList<>();

    2:size+get   List的专有遍历方式

     for(int i = 0;i

       al.get(i);

     }

    3:迭代器  Iterator it = al.iterator();  Collection的专有遍历方式

        while(it.hasNext()){

           it.next()

        }

  

    4:for-each--  任何集合都可以

     for(String s:al){

        s

     }

  

   Map集合遍历方式

     1:先找到所有的键吗,然后根据键获取值

       Map map = new HashMap<>();

        Set set = map.keySet();

        for(String s:set){

           String value = map.get(s);

        }

     2:直接获取键值对  entrySet

       Set> set = map.entrySet();

        for(EntrtSet en :set){

          en.getKey(); 键

          en.getValue(); 值

        }

 集合的工具类:Collections

           添加  add()

           删除 remove()

           修改

           排序 sort()

           二分搜索法:binarySearch()  前提是先排序

IO流

   字节流

  

    OutputStream

      FileOutputStream  文件字节输出流

      BufferedOutputStream 缓冲字节输出流

      ObjectOutputStream 序列化流  将对象流化(将java对象保存在文件)

    InputStream

      FileInputStream   文件字节输入流

      BufferedInputStream  缓冲字节输入流

      ObjectInputStream   反序列化流:将文件中对象读取取java程序中

   字符流         

    Writer

      OutputStreamWriter   字符输出转换流

      FileWriter           字符输出便捷流

      BufferedWriter       字符输出缓冲流

    Reader

      InputStreamReader    字符输入转换流

      FileReader           字符输入便捷流

      BufferedReader           字符输入缓冲流

     

     //3层结构的流 

      1:缓冲流

      2:转换流

      3:字节流

     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt")))

     BufferedReader bw = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")))

  流拷贝文件

    把d://工具/中国人.mp3 拷贝到当前项目

      BufferedInputStream bis = new BufferedInputStream("d://工具/中国人.mp3");

      BufferedOutputStream bos = new BufferedOutputStream("中国人.mp3");  

     

      byte[] by = new byte[1024];

      int num = 0;

      while((num = bis.read(by))!=-1){

        bos.write(by,num);

      }

     

      bos.close();

      bis.close();

     

     把d://工具/a.txt 拷贝到当前项目  

       BufferedReader br = new BufferedReader("d://工具/a.txt");

       BufferedWriter bw = new BufferedWriter("a.txt");

      

       String line = null;

       while((line = br.readLine())!=null){

         bw.write(line);

         bw.newLine();

       }

      

       bw.close();

       br.close();

 序列化:

      需要实现序列化的类要实现Serializable 接口

   方案1:

   Student stu1 = new Student();  

   Student stu2 = new Student(); 

  

   ObjectOutputStream oos = new ObjectOutputStream("Student.txt");

          oos.writerObject(stu1);

          oos.writerObject(stu2);

          oos.writerObject(null); //自定义结束标记

   oos.close();

  

  

   ObjectInputStream  ois = new ObjectInputStream("Student.txt");

   Object obj = null;

   while((obj = ois.readObject())!=null){

     Student stu = (Student)obj

   }

   ois.close();

  

   方案2:

   Student stu1 = new Student();  

   Student stu2 = new Student(); 

  

   ArrayList al = new ArrayList<>();

   al.add(stu1);

   al.add(stu2);

  

   ObjectOutputStream oos = new ObjectOutputStream("Student.txt");

    oos.writerObject(al);

   oos.close();

  

  

   ObjectInputStream  ois = new ObjectInputStream("Student.txt");

     ArrayLis al = (ArrayLis)ois.readObject();

     for(Student stu:al){

       stu

     }

   ois.close();

多线程

   实现方式

    1:继承Thread类,重写run方法

    2:实现Runnable接口,  重写run方法

  启动方式1  继承方案

   public class MyThread extends Thread{

  

     @OverRide

     public void run(){

         多线程

     }

    

     main(){

       MyThread m1 = new MyThread();

       MyThread m2 = new MyThread();

      

       m1.setName("线程1");

       m2.setName("线程2");

      

       m1.start();

       m2.start();

    

     }

  

  

   }  

  

         启动方式2  接口方式

 public class MyThread implements Runnable{

  

     @OverRide

     public void run(){

         多线程

     }

    

     main(){

       MyThread m1 = new MyThread();

     

      Thread t1 =new Thread(m1,"线程1");

      Thread t2 =new Thread(m1,"线程2");

    

       t1.start();

       t2.start();

    

     }

  

  

   }

线程声明周期

  新生:new对象

  就绪:调用start方法

  运行:谁抢到CPU执行,就运行

  阻塞:调用sleep()或者wait()

      休眠时间结束,进入就绪

      被唤醒进入就绪 (notify,notifyAll)

  死亡 stop,interrupted

          

线程同步

  1:同步代码块

     synchronized(锁对象){

         需要同步的代码...

     }

  2:同步方法

     public  synchronized void show(){

          需要同步的代码...

      }

  3:Lock锁  

   lock.lock();

           需要同步的代码...

   lock.unLock(); 

  

死锁

  public class DieLock implements Runnable{

   public static final Object objA = new Object();

   public static final Object objB = new Object();

  

   public boolean flag;

  

   public DieLock(boolean flag){

     this.flag = flag;

   }

   @OverRide

     public void run(){

         if(flag){

           synchronized(objA){

                 synchronized(objB){

                

                }

             }

        

         }else{

            synchronized(objB){

                 synchronized(objA){

                

                }

             }

         }

     }

    

     main(){

      DieLock d1 = new DieLock(true);

      DieLock d2 = new DieLock(false);

       Thread t1 = new Thread(d1);

       Thread t2 = new Thread(d2);

      t1.start();

      t2.start();

    

     }

  }  

线程通信

        相互等待,相互唤醒 

网络编程:Socket编程

 网络编程3要素

   1:IP地址  5类

   2:端口号   0-65535

   3:协议

     TCP

         面向连接 3次握手协议

         安全,效率低

         可传输大量数据

     UDP

                      非面向连接

                      不安全,下率高

                      传输数据量小

                      可以广播发送

  udp发送端

      1:创建发送端的socket

      DatagramScoket  ds = new DatagramScoket();

      2:创建数据包

      byte[] by = {97,98,99};

      DatagramPacket dp = new DatagramPacket(by,by.length,InetAddress.getLocalHost(),10086);

      3:发送数据包

      ds.send(dp);

      4:关闭socket

      ds.close();

  udp接受端    

      1:创建接受端的socket

      DatagramScoket  ds = new DatagramScoket(10086);

      2:创建数据包

      byte[] by = new byte[1024];

      DatagramPacket dp = new DatagramPacket(by,by.length);

      3:接受数据包

      ds.receive(dp);

      4:拆包

        byte[] by2 = dp.getDatea();   数据

        int len = dp.getLneght();  数据长度

        InetAddress  address = dp.getAddress(); 发送端的ip

        new String(by2,len);

      5:关闭socket

      ds.close();

  tcp客户端

     1:创建客户端的套接字

       Socket s = new Socket(InetAddress.getLocalHost(),10086);

     2:获取输出流

       BufferedOutputStream  bos = new BufferedOutputStream(s.getOutputStream());

     3:获取输入流

       BufferedIntputStream  bis = new BufferedIntputStream(s.getIntputStream());

     3:写数据

        bos.writer("你好吗".getBytes()); 

     4:通知服务器,写入数据完毕

        s.shutdownOutput();  

     5:读取服务器给出的响应

        bis.read();  

     6:关闭套接字

        s.close(); 

  tcp服务器端

     1:创建服务器端的套接字

     ServerSocket ss = new ServerSocket(10086);

     2:监听客户端套接字,并获取套接字

     Socket s = ss.accept();

     3:获取输入流

      BufferedIntputStream  bis = new BufferedIntputStream(s.getIntputStream());

     4 获取输出流

      BufferedOutputStream  bos = new BufferedOutputStream(s.getOutputStream());

     5:读数据

      byte[] by = new byte[1024];

      int num = 0;

      while((num = bis.read(by))!=-1){

         new String(by,num);

      }

     6:给出响应信息

      bos.write("反馈信息".geBytes());

      bos.flush();

     5:关闭套接字

      s.close();

 XML解析

   1:DOM解析

   2:SAX解析

   3:JDOM解析

   4:DOM4J解析

     

       SAXReader reader = new  SAXReader();

       Document doc = reader.read(new File(pathname));

       Element root = doc.getRootElements("Students");

       Iterator it = root.ElementIterator();

       while(it.hasNext){

        Element el = it.next();

         Attribute attr = el.attribute("id");

         attr.getName();属性名

         attr.getText();属性值

         Iterator it2 = el.ElementIterator();

         while(it.hasNext){

               Element el = it.next();

                Attribute attr = el.attribute("id");

                attr.getName();属性名

                attr.getText();属性值

                Iterator it2 = el.ElementIterator();

         }

       }

 正则表达式

          具有正确规则的字符串的表达式

   [0-9a-z_A-Z]

   {a}?  0-1

   {a}*  0-N

   {a}+  1-N

   {3,6}  3-6   

         

    判断

      boolean flag = "abc".matcher(regex)

    分割 

      String[] str = "a,c".split(regex);

    替换

      "abc".replaceAll("a",regex);

    获取

      String regex = "\\b[a-z]{3}\\b";

     Pattern pt = new Pattern();

     Matcher mt = pt.complie(regex);

     while(matcher.find()){

      mt.group();

     }

   

 反射

   1:获取Class

   Class clazz = Class.foName("java.lang.String"); 

   2:获取构造器 public

    Constructor con =  clazz.getConstructor(String.class);

           获取构造器 所有

    Constructor con2 =  clazz.getDeclaredConstructor(String.class);

   3:创建对象

    Object  obj = clazz.newInstance(); 无参对象

    Object obj = con.newInstance("字符串");

   4:获取属性

   Field field = clazz.getField("name",String.class);

   5 暴力破解

   field.setAccessable(true);

   6:属性赋值

    field.set(obj,"张三");

   7:获取属性值

   field.get(obj);

   8:获取方法

   Method m = clazz.getMethod("add",String.class);

   9调用方法

    Object obj = m.invoke(obj,"你好");

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


@ 注解能被用来为程序元素( 类、 方法、 成员变量等) 设置元数据。 值得指出的是, 注解不影响程序代码的执行, 无论增加、 删除注解, 代码都始终如一地执行。 如果希望让程序中的注解在运行时起一定
@ 1、线性表的概念 线性表是最常见也是最简单的一种数据结构。简言之, 线性表是n个数据元素的有限序列。 其一般描述为: A={a1,a2,……an) 一个数据元素通常包含多个数据项, 此时每个数据元
简介 ArrayList是开发中使用比较多的集合,它不是线程安全的,CopyOnWriteArrayList就是线程安全版本的ArrayList。CopyOnWriteArrayList同样是通过数组
在 Java String类源码阅读笔记 里学习了String类的源码,StringBuilder、StringBuffer是经常拿来和String类做对比的两个类,可谓是“爱恨纠缠” ,这里我们继续
话不多说,先上图。 1、基本概念 欲说线程,必先说进程。 进程:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程:线程是进程的一个执行路径,一个进程中至少有一个线程,进
@ 网络基础 计算机网络是指两台或更多的计算机组成的网络,在同一个网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一种网络协议。 那什么是互联网呢?互联网是网络的网络(internet
JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识。 先上图: 1、JVM基本概念 1.1、JVM是什么 JVM 的全称是 「Java Virtual Machine
@ 本文基于jdk1.8 HashMap采用 key/value 存储结构,每个key对应唯一的value。 在jdk1.7之前,HashMap 的内部存储结构是数组+链表。 在jdk1.8中 Has
@ Eclipse是很多Java开发者的第一个开发工具,尽管开源的Eclipse在一后起之秀的对比下,显得有些颓势,但是,Eclipse有着丰富的插件支持。选择合适的插件,Eclipse表示:老夫也能
@ 准备 LinkedList是基于双向链表数据结构实现的Java集合(jdk1.8以前基于双向循环链表),在阅读源码之前,有必要简单了解一下链表。 先了解一下链表的概念:链表是由一系列非连续的节点组
@ 写博客哪有刷逼乎有意思 1 写博客哪有刷逼乎有意思 2 写博客哪有刷逼乎有意思 3 类的加载、 连接和初始化 系统可能在第一次使用某个类时加载该类, 也可能采用预加载机制来加载某个类。 JVM 和
树结构是一类重要的非线性数据结构。直观来看,树是以分支关系定义的层次结构。树结构在客观世界广泛存在,如人类社会的族谱和各种社会组织机构都可用树来形象表示。 树在计算机领域中也得到广泛应用,尤以二叉树最
@ 本文基于jdk1.8 String类可谓是我们开发中使用最多的一个类了。对于它的了解,仅仅限于API的了解是不够的,必须对它的源码进行一定的学习。 一、前置 String类是Java中非常特别的一
随便打开一个招聘网站,看看对高级Java工程师的技能要求。 抛开其它的经验能力等等,单纯从技术,或者说知识上来讲,可以发现一些共通的地方。 Java基础 计算机基础 数据库,SQL/NoSQL 常用开
@ JDBC指Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。 1、JDBC典型用法 1.1、JDBC 4.2 常用接口和类简介
简介 ArrayList是基于数组实现的一种列表。 ArrayList继承体系如下: 图一:ArrayList继承体系 ArrayList实现了List, RandomAccess, Cloneabl
@ Java 的 IO 通过 java.io 包下的类和接口来支持, 在 java.io 包下主要包括输入、 输出两种 10 流, 每种输入、 输出流又可分为字节流和字符流两大类。 其中字节流以字节为
@ 使用断言 断言(Assertion)是一种调试程序的方式。在Java中,使用assert关键字来实现断言。 断言的概念 假设确信某个属性符合要求, 并且代码的执行依赖于这个属性。例如, 需要计算:
@ Java 程序在不同操作系统上运行时,可能需要取得平台相关的属性,或者调用平台命令来完成特定功能。 Java 提供了 System 类和 Runtime 类来与程序的运行平台进行交互。 Syste
@ Java 提供了一个操作 Set 、 List 和 Map等集合的类:Collections , 该工具类里提供了大量方法对集合元素进行排序、 查询和修改等操作,还提供了将集合对象设置为不可变、对