java.lang.String is NOT immutable

I found some code on a Java mailing list that challenges a lot of the assumptions about how strings work in Java.

There is a standard newbie question about immutable strings. It goes like this:
What gets printed out:

String lc = "lowercase";
lc.toUpperCase();
System.out.println(lc);

The standard answer is that you get "lowercase" because in Java, strings are immutable. The standard answer goes on to explain the benefits to security of having immutable strings, and how values can't be changed after they've been checked. I'm sure you've seen it all before.

So what about the following code:

String lc = "lowercase";
Mutant.toUpperCase(lc);
System.out.println(lc);

You'd think that because Mutant wasn't even part of the String class that it couldn't alter lc, but Mutant.toUpperCase(lc); uses a simple reflection trick to edit the string:

public static void toUpperCase(String orig)
{
    try
    {
        Field stringValue = String.class.getDeclaredField("value");
        stringValue.setAccessible(true);
        stringValue.set(orig, orig.toUpperCase().toCharArray());
    }
    catch (Exception ex)
    {
    }
}

The original article goes into a lot more depth, and a follow-up shows how to change the values of Integers too!.

The solution to the problem is to run your code with a Security manager turned on. That way you can be sure that people are not messing about with private variables.

Comments

Comments have been turned off on old posts