走进JDK之不可变类字符串

  

文中相关源码:String.java

  

今天来说说字符串。
  

  

贯穿全文,你需要始终记住这句话,字符串是不可变类。其实前面说过的所有基本数据类型包装类都是不可变类,但是在字符串的源码中,不可变类的概念体现的更加淋漓尽致,所以,在阅读字符串源码的同时,抽丝剥茧,你会对不可变类有更深的理解。
  

  


  

  

首先来看一下什么是不可变类?有效的Java第三版第17条使不可变性最小化中对不可变类的解释:

  
  

不可变类是指其实例不能被修改的类。每个实例中包含的所有信息都必须在创建该实例的时候就提供,并在对象的整个生命周期(生命周期)内固定不变。
  为了使类成为不可变,要遵循下面五条规则:

  

不要提供任何会修改对象状态的方法(也称为设值方法)。
  保证类不会被扩展。为了防止子类化,一般做法是声明这个类成为最终的。
  声明所有的域都是最终的。
  声明所有的域都为私有的。这样可以防止客户端获得访问被域引用的可变对象的权限,并防止客户端直接修改这些对象。
  确保对于任何可变组件的互斥访问。如果类具有指向可变对象的域,则必须确保该类的客户端无法获得指向这些对象的引用,并且,永远不要用客户端提供的对象引用来初始化这样的域,也不要从任何访问方法(accessor)中返回该对象引用。在构造器,访问方法和readObject方法(详见第88条)中请使用保护性拷贝(防御性复制)技术(详见第50条)。

     

根据这五条原则,来品尝一下字符串。java吧!
  

  


  

        最后公共类字符串   java实现。可序列化的,Comparable      

对应原则第二点保证类不会被扩展,使用最后修饰。此外:

  
      <李>实现了可序列化的接口,具备序列化能力李   <李>实现了可比接口,具备比较对象大小能力,根据单字符的大小比较。   <李>实现了CharSequence进行接口,表示是一个字符序列,实现了该接口下的一些方法。   
  

<强>字段
  

        私人最终char[]价值;//储存字符串   私人int散列;//哈希值,默认为0   私有静态最终长serialVersionUID=-6849794470754667710 l;//序列化标识      

看起来的字符串是一个独立的对象,其实它是使用基本数据类型的数组char[]实现的作。为使用者,我们不需要打开弦的黑匣子,直接根据它的API使用就可以了,这正是Java的封装性的体现。但是作为开发者,我们就有必要一探究竟了。
  

  

<代码>私人最终char[]价值>   

  


  

  

字符串的构造函数很多,大致可以分为以下四种:
  

  

<强>无参构造
  

        公共字符串(){   this.valuehttps://www.yisu.com/zixun/=" value;   }      

无参构造默认构建一个空字符串。鉴于字符串是不可变类,所以此构造器并没有什么意义,一般你也不会去构建一个不可变的空字符串对象。
  

  

参数是byte []
  

        公共字符串(字节字节[]){}   公共字符串(int[],字节字节偏移量,int长度){}   公共字符串([],字符集字节字节字符集){}   公共字符串(字符串字节字节[],charsetName) {}   公共字符串(int[],字节字节偏移量,int长度、字符集字符集){}   公共字符串(int[],字节字节偏移量,int长度字符串charsetName) {}      

已经废弃的就不再列举了。上面这些构造函数都差不多,最后都是调用StringCoding.decode()方法将字节数组转换为字符数组,再赋值给价值[]。这里要注意一点,参数未指定编码格式的话,默认使用系统的编码格式,如果没有获取到系统编码格式,则使用iso - 8859 - 1格式。
  

  

<强>参数是char[]
  

  

参数是char[]的构造函数有3个,逐个看一下:
  

        公共字符串(char[]价值){   这一点。值=https://www.yisu.com/zixun/Arrays.copyOf(价值,value.length);   }

走进JDK之不可变类字符串