查看代码。
String xx=new String("hello world");
String yy="hello world";
System.out.println("xx: " + xx);
System.out.println("yy: " + yy);
System.out.println("xx==yy:"+(xx==yy)); // false
//modify the value of yy using reflection
Field yyfield=String.class.getDeclaredField("value");
yyfield.setAccessible(true);
char[] value=(char[])yyfield.get(yy); // change the value of yy
value[5]='_';
System.out.println("xx: " + xx); // xx's value also changed.why?
System.out.println("yy: " + yy);
System.out.println("xx==yy:"+(xx==yy)); //false
我看过一些关于Literal Pool的帖子,知道 xx 和 yy 指向不同的地方。但为什么我改变 yy 的值, xx 也改变了。在反思或其他一些我不知道的方面是否有任何操作?提前谢谢。
答案 0 :(得分:3)
xx
和yy
是两个不同的String
个实例,但它们引用相同的内部char[]
数组。
这是一个特定于实现的细节,并在Java版本之间进行了更改。在过去,构造函数String(String)
提供了一种方法来创建一个String
,其中包含一个新的char[]
数组,用于源String
是一个子字符串的情况。大字符串。但是,当前实现已经在subString
操作中分配了较小的数组和副本内容,从而无需在构造函数中进行复制,因此构造函数String(String)
只使用相同的数组引用。
更奇特的是,最新的(Java 8)JVM具有String
重复数据删除功能,而垃圾收集器一旦发现两个{{1},就会将数组引用更改为指向同一个数组实例具有相同的内容。因此它可以收集两个数组中的一个,同时保持相同的语义。
答案 1 :(得分:2)
实例字段value
与xx
和yy
的实例相同。该值也对应于在字符串池中实现的文字。