池和堆之间的关系

时间:2015-03-11 14:13:58

标签: 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 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 也改变了。在反思或其他一些我不知道的方面是否有任何操作?提前谢谢。

2 个答案:

答案 0 :(得分:3)

xxyy是两个不同的String个实例,但它们引用相同的内部char[]数组。

这是一个特定于实现的细节,并在Java版本之间进行了更改。在过去,构造函数String(String)提供了一种方法来创建一个String,其中包含一个新的char[]数组,用于源String是一个子字符串的情况。大字符串。但是,当前实现已经在subString操作中分配了较小的数组和副本内容,从而无需在构造函数中进行复制,因此构造函数String(String)只使用相同的数组引用。

更奇特的是,最新的(Java 8)JVM具有String重复数据删除功能,而垃圾收集器一旦发现两个{{1},就会将数组引用更改为指向同一个数组实例具有相同的内容。因此它可以收集两个数组中的一个,同时保持相同的语义。

答案 1 :(得分:2)

实例字段valuexxyy的实例相同。该值也对应于在字符串池中实现的文字。