类加载对一个类只会进行一次。
"xyz" 在类加载时就已经创建并驻留了(如果该类被加载之前已经有 "xyz" 字符串被驻留过则不需要重复创建用于驻留的"xyz"实例)。
驻留的字符串是放在全局共享的字符串常量池中的。
在 HotSpot VM 里实现的 string pool 功能的是一个 StringTable 类,它是一个哈希表,里面存的是驻留字符串(也就是我们常说的用双引号括起来的)的引用(而不是驻留字符串实例本身)
也就是说在堆中的某些字符串实例被这个 StringTable 引用之后就等同被赋予了”驻留字符串”的身份。
这个 StringTable 在每个 HotSpot VM 的实例只有一份,被所有的类共享。
在这段代码后续被运行的时候,"xyz" 字面量对应的 String 实例已经固定了(前面的类加载过程),不会再被重复创建。
所以这段代码将常量池中的对象复制一份放到 heap 中,并且把 heap 中的这个对象的引用交给 s1 持有。
对于这句代码,可分为两个过程:
将new String("xyz")拆分为new String()和"xyz"
如果写在类方法里,请参考前面的类加载,就是相比之下提前驻留了吧。
String a = new String("abc"); String b = "abc"; System.out.println(a == b);//false
String a = new String("abc"); String b = "abc"; String c = new String("abc"); System.out.println(c == a);//false System.out.println(c == b);//false System.out.println(a == b);//false