String类 1.String类声明为final,不可被继承。不可变 的字符序列,简称不可变性。 
String的不可变性 先看一个例子:
1 2 3 4 5 6 7 8 9 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  "abc" ;"abc" ;
输出结果:
true
 
原因:字面量字符串储存在字符串常量值,一样的字符串只储存一个。则通过字面量赋值的s1和s2指向同一个字符串,即地址值一样。通过字面量方式(区别于new)给一个字符串赋值,此时的字符串值生命在字符串常量池中,字符串常量池中是不会存储相同内容的字符串的。 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  "abc" ;"abc" ;"==========================" );"abc" ;"def" ;"==========================" );'a' ,'m' );
true true
 
当不管是调用String方法,比如replace,来修改值,还是拼接还是更改引用,只要和原来值不一样,就是在字符串常量池新造一个字符串,来更改引用,原value没有变。String代表不可变的字符序列。 
String类的赋值 有四种主要方式,除此之外还有比较多的API,比如用StringBuffer和StringBuilder赋值等。new和字符串字面量赋值的区别? 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  "abc" ;new  String("abc" );new  String("abc" );
输出结果:
true
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  demo03;public  class  Person  int  age;public  Person ()  public  Person (String name, int  age)  this .age = age;this .name = name;
再来测试一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  new  Person("tom" ,12 );new  Person("tom" ,12 );new  Person(new  String("tom" ),12 );new  Person(new  String("tom" ),12 );
结果:
true
 
内存结构如下:
进一步验证了String类的不变性。
String类不同拼接操作的对比 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  "hello" ;"world" ;"helloworld" ;"hello"  + "world" ;"world" ;"hello" +s2;
结果:
true
 
两个字面量字符串通过+连接,相当于一个字面量 ,也就是s3和s4指向同一个字符串常量池中的字面量字符串。而赋值过程有变量名(注意并非是final修饰的变量,final修饰后为常量,储存在常量池)参与而不是字面量直接参与,则此时不在常量池了 ,需要在堆空间中开辟,相当于new。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  "hello" ;"world" ;"helloworld" ;"hello"  + "world" ;"world" ;"hello" +s2;
true
 
String与byte数组之间的转换 String –> byte[]:调用String的getBytes() 1 2 3 4 5 6 7 8 9 10 11 12 package  demo03;import  java.util.Arrays;public  class  StringTest  public  static  void  main (String[] args)  "abc123" ;byte [] bytes = s.getBytes();
[97, 98, 99, 49, 50, 51]
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  demo03;import  java.util.Arrays;public  class  StringTest  public  static  void  main (String[] args)  "中文" ;byte [] bytes2 = s2.getBytes();
[-28, -72, -83, -26, -106, -121]
 
默认UTF-8编码 一个中文对三个字节。 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  demo03;import  java.io.UnsupportedEncodingException;import  java.util.Arrays;public  class  StringTest  public  static  void  main (String[] args)  throws  UnsupportedEncodingException "中文" ;byte [] bytes2 = s2.getBytes("gbk" );
[-42, -48, -50, -60]
 
gbk编码下一个中文对两个字节 
解码通过String的构造器实现 1 2 3 4 5 6 7 8 9 10 11 12 package  demo03;public  class  StringTest  public  static  void  main (String[] args)  byte [] b = new  byte []{ 97 , 98 , 99 , 49 , 50 , 51 };new  String(b);
abc123
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  demo03;import  java.io.UnsupportedEncodingException;public  class  StringTest  public  static  void  main (String[] args)  throws  UnsupportedEncodingException byte [] b = new  byte []{-42 , -48 , -50 , -60 };new  String(b,"gbk" );
中文
 
要注意编码集和解码集一致,否则会出现乱码。 
String、StringBuffer和StringBuilder的异同 String:不可变的字符序列,底层使用char[]存储。 
可变性 1 2 3 4 5 6 7 8 9 10 11 12 package  demo03;public  class  SBTest  public  static  void  main (String[] args)  new  StringBuffer("abc" );0 ,'m' );'d' );
mbc
 
底层实现 
1 2 3 4 5 6 7 8 9 package  demo03;public  class  SBTest  public  static  void  main (String[] args)  new  StringBuffer("abc" );
3
 
length源码: 
扩容问题:如果要添加的数据底层数组装不下了,如何扩容? 默认情况下,扩容为原来的容量的二倍再+2,同时将原有的数组中的元素复制到新数组中。 添加null字符串 
1 2 3 4 5 6 7 8 9 10 11 12 package  demo03;public  class  SBTest  public  static  void  main (String[] args)  null ;new  StringBuffer();
null
 
4
构造器添加null字符串 
1 2 3 4 5 6 7 8 9 10 11 package  demo03;public  class  SBTest  public  static  void  main (String[] args)  null ;new  StringBuffer(str);
产生NullPointerException
 
常用方法 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  demo03;public  class  SBTest  public  static  void  main (String[] args)  new  StringBuffer("abc" );1 );'1' );2 ,4 );new  StringBuffer("abc11" );2 ,4 ,"hello" );new  StringBuffer("abc" );1 ,false );
abc11
 
效率对比 StringBuilder>StringBuffer>>String