0

I know String is meant to be final, immutable and whats not.

However, I wondered for quite a while why it's so, and more importantly, how this is achieved.

Turns out, it is not achieved at all, it's merely a made up artificial restriction, at least so it seems.

Here' we have a "cat" string, and will fill it with "NYAN NYAN" content:

package hackstring;

import java.lang.reflect.Field;    

public class Main {
    public static void main(String[] args)
    {
        String str = "cat";

        System.out.println(str);

        modifyString(str, "NYAN NYAN");

        System.out.println(str);
    }

    private static void modifyString(String modified, String newContent) {
        try {
            Field val = modified.getClass().getDeclaredField("value");
            val.setAccessible(true);

            Field count = modified.getClass().getDeclaredField("count");
            count.setAccessible(true);

            char[] injected = newContent.toCharArray();
            count.set(modified, injected.length);
            val.set(modified, injected);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Clearly, this is not meant to be done, but - it ACTUALLY WORKS!

cat
NYAN NYAN

So, if String is mutable, why are they feeding us this nonsense about it's immutability?

Like, if they wanted it to be truly immutable, why not make it a primitive type? This is just making fools of us, nothing else.

(This may not be strictly a question. Just something to think about..)

MightyPork
  • 18,270
  • 10
  • 79
  • 133
  • 11
    Reflection allows you to do most anything. When doing it you say "I know what I'm doing, just trust me". Things like immutability, private, protected etc are all to stop you making **honest mistakes**. If you actually want to, you can get around all of them and they shouldn't be considered security measures – Richard Tingle Apr 29 '14 at 07:36
  • Yeah, but now that strings can be used in `switch`es.. you can't really modify int constant, but with strings, it all sounds like a joke. – MightyPork Apr 29 '14 at 07:37
  • 1
    You could make the same argument with reflection about so-called `private` members of objects. – merlin2011 Apr 29 '14 at 07:37
  • 7
    Note that reflection is prohibited in reduced-trust environments, too. If you don't trust the code you're running *not* to do this, you should use a security manager. – Jon Skeet Apr 29 '14 at 07:37
  • 2
    Incidently, if you want to really break java [you can make `Integer` 1 == 42](http://thedailywtf.com/Articles/Disgruntled-Bomb-Java-Edition.aspx). Once you start messing with reflection all bets are off – Richard Tingle Apr 29 '14 at 07:41
  • String is not truly immutable, have a look at `hashCode` it is not final, for a good reason. Basically if you mess about enough you get a mess, no surprise there ;) – Peter Lawrey Apr 29 '14 at 07:49
  • 1
    @RichardTingle if you really want to mess about you can use Unsafe to modify the header of an object and change it's Object.hashCode(), or even it's class ;) – Peter Lawrey Apr 29 '14 at 07:50
  • From this point of view no class is immutable – Richard Tingle Apr 29 '14 at 07:51

0 Answers0