前言
下面对String类的创建方式和如何判断两个String类是否相等做了总结。
String的基础
String被声明为final,因此String类不可被继承。在Java 8中,String类使用char数组存储字符串。并且char数组被声明为fianl,即保证了String不可变。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
字符串常量池(String Pool)
字符串常量池保存着所有字符串的字面量,这些字面量在编译时期就确定。可以在运行过程中通过String的intern()方法将字符串添加到String Pool中。
在JDK 1.7之前,当一个字符串调用intern()方法时,如果给字符串的字面量不是首次出现,则返回String Pool中存在字符串的引用,否则 ,就会把该字符串的字面量复制到String Pool中。在JDK 1.7之后,当一个字符串调用intern()方法时,如果该字符串的字面量不是首次出现,则返回String Pool中存在的字符串的引用,否则,就会把该字符串的引用复制到String Pool中。
示例1:
String s1 = new String("aaa");// 在堆中创建s1对象,同时在String Pool中添加字符串"aaa"的字面量
String s2 = new String("aaa");// 在堆中创建s2对象,String Pool中已经存在"aaa"字面量,已无需添加
System.out.println(s1 == s2); // false 因为s1和s2指向堆中两个不同的对象
String s3 = "aaa"; // 直接指向String Pool中的字面量"aaa"
String s4 = s2.intern(); // 返回String Pool中字面量"aaa"的引用
System.out.println(s3 == s4); // true 因为s3和s4都指向String Pool中的字面量"aaa"
示例2:
String s1 = "bbb"; // 自动将字符串字面量"bbb"放入String Pool中,并指向它
String s2 = "bbb"; // s2指向String Pool中的字面量"bbb"
System.out.println(s1 == s2); // true 因为s1和s2都指向String Pool中的字面量"bbb"
示例3:
String str1 = new StringBuffer("计算机").append("软件").toString();// StringBuffer或StringBuilder的append()方法不会把拼接的字面量"计算机软件"放入String Pool中
str1.intern(); // 对象str1指向的字面量"计算机软件"在String Pool中首次出现,所以itern()方法将对象str1的引用放入String Pool中
String str2 = "计算机软件"; // str2指向String Pool中的字面量"计算机软件"
System.out.println(str1 == str2); // true