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
实现字符串相等,不必担心实例