2

See the code.

    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

I've seen some posts about Literal Pool, know xx and yy point to different place. But why I change the value of yy, xx also changed. Is there any operation in reflection or some other aspects I don't know? Thanks in advance.

Community
  • 1
  • 1
kkwang
  • 247
  • 2
  • 11

2 Answers2

3

xx and yy are two distinct String instances but they refer to the same internal char[] array.

This is an implementation-specific detail and changed between the Java versions. In the past, the constructor String(String) offered a way to create a String with a new char[] array for the case that the source String is a sub-string of a much larger string. However, current implementations allocate a smaller array and copy contents in the subString operation already, eliminating the need for copying in the constructor, hence the constructor String(String) simply uses the same array reference.

Even more fancy, the most recent (Java 8) JVMs have a String de-duplication feature whereas the garbage collector will change the array references to point to the same array once it found out that two String instances have the same contents. So it can collect one of the two arrays while maintaining the same semantics.

Holger
  • 285,553
  • 42
  • 434
  • 765
2

The instance field value is the same instance for both xx and yy. This value also corresponds to the literal that's interned in the string pool.

M A
  • 71,713
  • 13
  • 134
  • 174
  • Got it. My understand is : since String is unchangeable , they can share the char[] object? – kkwang Mar 11 '15 at 14:22
  • @wjk Yes they share the same `char[]` object but this has nothing to do with the `String` class being immutable. This has to do with caching string constants in the JVM. – M A Mar 11 '15 at 14:28