如果是使用字面量的形式创建的字符串对象,该对象会存放在StringTable中,且StringTable里只有一份值相同的字符串对象;
如果是使用new的形式创建的字符串对象,该对象会存放在堆中,当然StringTable也是在堆中,只是它们两是在不同区域;
如果创建值相同的多个字符串对象,使用字面量的形式创建肯定返回的是在StringTable里的引用,而使用new返回的是在堆中的引用,所以地址肯定不同,但是它们的value属性指向的是同一个char[]对象,地址是相同的;
public static void main(String[] args) throws Exception{
String s1 = "a";
String s2 = new String("a");
String s3 = new String("a");
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
char[] value1 = (char[]) value.get(s1);
char[] value2 = (char[]) value.get(s2);
char[] value3 = (char[]) value.get(s3);
// 字符串如果值相同,那么它们存储的是同一个字符数组
System.out.println(value1 == value2);
System.out.println(value2 == value3);
}
可以看到,值相同的字符串虽然字符串对象可能不同,但它们的value属性指向的都是同一个对象,即对于String来说,只会创建一个值相同的char[]数组。