由于在Effect JAVA一书中看到第51条:当心字符串连接的性能,衍生出这个问题,由此转载
一、java内部String类的实现:
java 8:
1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { 3 /** The value is used for character storage. */ 4 private final char value[]; 5 }
java 9 及之后:(使用coder标识了编码)
1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { 3 /** The value is used for character storage. */ 4 private final byte[] value; 5 6 /** The identifier of the encoding used to encode the bytes in 7 {@code value}. */ 8 private final byte coder; 9 }
二、为何要将String定义为final不可变?
因为在程序编写的过程中,会大量地用到String常量,如果每次声明一个String引用都要新建一个String对象,那么会造成空间的极大浪费。于是,在java的堆中开辟了一块存储空间String pool,用于存储String常量对象。当有多个String引用指向同样的String字符串时,实际上是指向的是同一个Sting pool中的对象,而不需要额外的创建对象。
1 public class Test{ 2 public static void main(String [] args){ 3 String a="abc"; 4 String b="abc";//对象保存在string pool中 5 String c=new String("abc");//以new创建的对象保存在堆中 6 System.out.println("a==b:"+(a==b)); 7 System.out.println("a==c:"+(a==c)); 8 9 } 10 }
实现String pool就需要String定义为final,否则,当引用a、b都指向“abc”时,通过a将对象改变后,引用b所指向的对象被动地改变了。那程序员不得气得半死?
三、String不可变的其他好处
1、以String作为HashMap的key,String的不可变保证了hash值的不可变。
2、String作为网络连接的参数,它的不可变性提供了安全性。
3、String不可变,所以线程安全。