title: "Mutable" Java String is acting unpredictable
body: <p>I was playing a bit with changing String value (i know that it's extremely unsafe and dangerous) with function:</p>
  
  <pre><code>public static void reverse(String s) {
      try {
          Field val = String.class.getDeclaredField("value");
          val.setAccessible(true);
          char[] value = (char[]) val.get(s);
          char[] inverse = s.toCharArray();
          for (int i = 0; i &lt; s.length(); i++)
              value[i] = inverse[s.length()-i-1];
      }
      catch (Exception e) {
          e.printStackTrace();
      }
  }
  </code></pre>
  
  <p>and after while I've discovered that depending on string creation it is acting extremely unpredictable. I've created a small mind-game with that (so many prints was necessary to get wanted effect):</p>
  
  <pre><code>public static void main(String[] args) {
      final String a = "abc";
      final String b = new String("abc");
      final String c = "abcd".substring(0, 3);
  
      System.out.println("Let's start!");
      System.out.print("a - ");
      System.out.println(a);
      System.out.print("b - ");
      System.out.println(b);
      System.out.print("c - ");
      System.out.println(c);
  
      System.out.print("Are they all equals? - ");
      System.out.println(a.equals(b) &amp;&amp; a.equals(c) &amp;&amp; b.equals(c));
  
      System.out.print("But they are different objects, right? - ");
      System.out.println(!(a == b || b == c || a == c));
  
      System.out.println("Let's reverse only 'a'. But all are final and String is not mutable, so what can go wrong?");
  
      reverse(a);
  
      System.out.println("Done. What we've got here?");
  
      // trick 1
      System.out.print("a = ");
      System.out.print(a);
      System.out.println(" - ok, 'a' is reversed. A bit strange, but it works. Super method");
      System.out.print("b = ");
      System.out.print(b);
      System.out.println(" - wait... We haven't touched this");
      System.out.print("c = ");
      System.out.print(c);
      System.out.println(" - this is untouched, wierd, huh? We've just reversed 'a' so 'b' and 'c' should act the same.");
  
      // trick 2
      System.out.println("\nOk, so 'c' should equals \"abc\", right?\n");
      System.out.println("\"abc\".equals(c)? = "+"abc".equals(c));
      System.out.println("...\n");
  
      System.out.print("Do you remeber, that");
      System.out.print(" a = ");
      System.out.print(a);
      System.out.print(" oraz b = ");
      System.out.print(b);
      System.out.println(" ?\n");
  
      // trick 3
      System.out.println("So let's check that");
      System.out.print("a.equals(b) = ");
      System.out.println(a.equals(b)+"\n");
      System.out.println("Ok, we had expected that.\n");
      System.out.println("But what do you think the result of (\" \"+a).equals(\" \"+b) will be?\n");
      System.out.print("(\" \"+a).equals(\" \"+b) = ");
      System.out.println((" "+a).equals(" "+b)+"\n");
  
      System.out.print("And do you remeber, that");
      System.out.print(" a = ");
      System.out.print(a);
      System.out.print(" ,a c = ");
      System.out.print(c);
      System.out.println(" ?\n");
  
      // trick 4
      System.out.println("So let's check if they are different:");
      System.out.print("a.equals(c) = ");
      System.out.println(a.equals(c));
      System.out.println("So they are different... but are they really different?\n");
      System.out.print("(\" \"+a).equals(\" \"+c) = ");
      System.out.println((" "+a).equals(" "+c));
      System.out.println("Booo!!! You could choose the blue pill!\n");
  
      System.out.println("Our actors were: ");
      System.out.print("a = ");
      System.out.print(a);
      System.out.print(", b = ");
      System.out.print(b);
      System.out.print(", c = ");
      System.out.print(c);
      System.out.print(" oraz abc = ");
      System.out.println("abc");
      System.out.print("\n");
  
      // trick 5
      System.out.println("Or in other words");
      System.out.println("a = "+a+", b = "+b+", c = "+c+" oraz abc ="+(" "+"abc")+"\n");
  
      System.out.println("But do you remember what we were revering? Was is rally b?");
      System.out.println("Have a nice day. Z-DNA");
  }
  </code></pre>
  
  <p>But I don't get that play. All string are different object but with the same value.  </p>
  
  <p>So why in trick 1 string 'c' acted differently that 'b'?  </p>
  
  <p>Ok, I get trick 2. The "abc" is not anymore "abc" but "cba" (but why? I have changed value of String 'a', not value of string pool) so it can't be equal "abc", but how 'c' can be "abc" when I can't even get "abc" calling "abc"??  </p>
  
  <p>Why in trick 3 after adding space 'a' and 'b' was not equal anymore and why on earth in 4 'a' and 'c' with spaces <strong>was equal?!?!</strong></p>
  
  <p>Trick 5 show us that the value of 'a', 'b', 'c' and "abc" is changing depend on how are we calling it. (oh wait. 'c' is special. The most irrational method of creating string is actually most immune to that black magic). </p>
  
  <p>Please help me understanding what I've actually done and what sort of darkness is function reverse.</p>