3

All of us know that String is immutable in java - content can not be changed once the string is created.


String uses character array char[] value to store string content, here is the java code -

/** The value is used for character storage. */
    private final char value[];

What if we get access to the field values[] and we change it? See this code -

            String name = "Harish";
            System.out.println(name); // Harish           
            Field field = name.getClass().getDeclaredField("value");
            field.setAccessible(true);
            char[] value = (char[]) field.get(name);
            value[0] = 'G';
            value[1] = 'i';
            System.out.println(Arrays.toString(value)); // [G, i, r, i, s, h]
            System.out.println(name); // Girish

This way, i think, we can change content of the string which goes against the String Immutability Principle.

am i missing something?

Harish
  • 169
  • 1
  • 2
  • 7
  • You are not changing anything in the String.... It seems you don't truly understand what is going on in the background. you can re-reference the reference variable, it'll just point to a newly created String, the original String is still the same, just no longer referenced to by that variable. – Stultuske Jun 04 '15 at 20:19
  • 3
    @Harish, yes, if you hack any piece of software to make it break its own explicitly declared contract, then it won't work as specified in its explicitly declared contract. This should surprise no one. – 0xbe5077ed Jun 04 '15 at 20:21
  • 2
    @Stultuske *"the original String is still the same"* Wrong. – Tom Jun 04 '15 at 20:26

1 Answers1

7

No, you're not missing anything. When you use reflection and make inaccessible fields accessible, you explicitely ask to lose all the guarantees offered by the type when it's used in a "normal" OOP way.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • so in this case, are we changing content of original string (harish) or are we getting a different (new string "Girish") string? – Harish Jun 04 '15 at 20:25
  • 1
    @Harish You're changing the original one. You can easily tell by adding the following lines to the **end** of your code `String name2 = "Harish"; System.out.println(name == name2); System.out.println(name.equals(name2));`. Here you're asking for the literal *"Harish"*, just after you changed it to *"Girish"* (both SOP prints *true*). You'll get the same reference, which also equals to "Girish". This means. – Tom Jun 04 '15 at 20:30