奇怪的Java基础知识增加了:String

Java8中String部分源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
}

String被声明为final,因此该类是不可被继承的。(Integer等包装类也不可被继承。)
在Java8中,String内部使用char数组进行存储数据,在Java9之后,改用了byte数组进行存储,同时使用coder来标识使用了哪种编码。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final byte[] value;

    /** The identifier of the encoding used to encode the bytes in {@code value}. */
    private final byte coder;
}

value数组用final修饰,故value值被初始化以后就不能再改变,保证了String的不可变性。

不可变的好处

  1. 可以缓存hash值
    因为String的hash值经常被使用,比如用在HasMap中的key。不可变的特性可以是的hash值也不可变,因此只需进行一次计算。
  2. String Pool的需要
    当一个String对象被创建后,会将其存储堆内存中,若调用intern()方法,会将其添加到字符串常量池中,并返回指向该常量的引用,此后若再次调用,因为常量池已经存在,所以直接返回对应的引用。
  3. 安全性
    String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 的那一方以为现在连接的是其它主机,而实际情况却不一定是。
  4. 线程安全
    可以在多个线程中安全地使用。

String、StringBuffer and StringBuilder

  1. 可变性
  • String不可变。
  • StringBuffer和StringBuilder可变。
  1. 线程安全
  • String不可变,所以是线程安全的。
  • StringBuilder不是线程安全的。
  • StringBuffer是线程安全的,内部使用synchronized进行同步。

String Pool

		String a = new String("123");
		String b = new String("123");
		System.out.println(a == b);	//a、b都是通过new的方式创建,所以结果为false
		String c = "123";	//此方式可以认为是a.intern()
		String d = "123";	//此方式可以认为是a.intern()
		System.out.println(c == d); //c、d取到的都是常量池中的相同引用,故返回true

你可能感兴趣的:(Java基础)