Java 池和堆之间的关系
请参阅代码Java 池和堆之间的关系,java,string,reflection,Java,String,Reflection,请参阅代码 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 reflectio
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
我看过一些关于的帖子,知道xx和yy指向不同的地方。但是为什么我改变了yy的值,xx也改变了。在反射或其他方面是否有我不知道的操作?提前感谢。
xx
和yy
是两个不同的String
实例,但它们引用相同的内部char[]
数组
这是一个特定于实现的细节,在Java版本之间进行了更改。在过去,构造函数String(String)
提供了一种使用新的char[]
数组创建String
的方法,用于源String
是更大字符串的子字符串的情况。但是,当前的实现已经在子字符串
操作中分配了一个较小的数组并复制内容,从而消除了在构造函数中复制内容的需要,因此构造函数字符串(String)
仅使用相同的数组引用
更奇怪的是,最新的(Java8)JVM有一个
String
重复数据消除功能,而垃圾收集器一旦发现两个String
实例具有相同的内容,就会将数组引用更改为指向相同的数组。因此,它可以收集两个数组中的一个,同时保持相同的语义。实例字段值
对于xx
和yy
都是相同的实例。此值还对应于字符串池中的文本。一个简单的测试是比较两个字符串的char数组引用:P@TheLostMind干得好,我试试看,明白了。我的理解是:由于字符串是不可更改的,所以它们可以共享char[]对象?@wjk是的,它们共享相同的char[]
对象,但这与String
类是不可变的无关。这与在JVM中缓存字符串常量有关。是的,它们已经解决了。谢谢大家。Brajsimple始终使用equals
实现字符串相等,不必担心实例