<< Mutable Strings + Hungarian Notation + Security = ??? | Home | New features in DWR 0.8 >>

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.



Re: java.lang.String is NOT immutable

Well, duh. If you use reflection to play with private fields, it's obviously not going to be immutable. Neither is any other "immutable" class you can come up with.

Re: java.lang.String is NOT immutable

Wow. Good job. You found something everyone else read 4 years ago. Duh is right.

Just adding my personal DUH

Its imutable for purposes of security. If you don't have the appropriate VM permissions you can't run that code. Try placing it in an applet.

Re: java.lang.String is NOT immutable

I think people are being too hard on you. keep on trucking

Re: java.lang.String is NOT immutable

I didn't know this little tidbit - so thanks. And ignore the other pricks.

Re: java.lang.String is NOT immutable

LOL! If I ever catch someone using code like this in a serious piece of software, they will end up on http://www.thedailywtf.com/ !

Re: java.lang.String is NOT immutable

'lc.toUpperCase()' returns a NEW string, it does no modification on lc. So it is wrong to say that it fails because the value is immutable--it fails because you didn't know how to use the method.

Re: java.lang.String is NOT immutable

That's interesting. Is there a simple case when you'd want to do this rather than just saying lc = lc.toUpperCase();

Re: java.lang.String is NOT immutable

There is something like Java meta knowledge. This is about sane use of the Java language. It is not what you know about the syntax which makes you a good programmer. It is about when and how you use the language.

Re: java.lang.String is NOT immutable

You do not get far with your reflection hacking if you run a SecurityManager. Then you need a ReflectPermission to do such potentially insecure operations which are endangering data integrity.

Re: java.lang.String is NOT immutable

You do not get far with your reflection hacking if you run a SecurityManager. Then you need a ReflectPermission to do such potentially insecure operations which are endangering data integrity.

Re: java.lang.String is NOT immutable

Seems to me the basic types (value types) are better left immutable as they have no unique identity in an application - they only have a value. They are used to build the identity of the active objects. For a different value, use a different object - this way objects can hold their basic properties by sharing references to value types instead of cloning them to ensure they don't change everywhere when one object decides it needs a different property value. When everything is accessed via references, it's the safest way to work. There isn't a language yet devised in which it isn't possible to write bad programs, abuse the facilities.

Re: java.lang.String is NOT immutable

> Seems to me the basic types (value types) are better left immutable <snip>

Your point rests on an assumption that some would argue with: that String is effectively a 'primitive' like int or float, which are clearly intended to be 'value types'. But is it?

I don't feel strongly one way or the other, but just to play Devi's advocate...

If String were intended to be purely a 'value type' than the language designers (Gosling and Co.) should have made it a primitive. But it isn't. It's an object. Why make it an object and then make it immutable?

This made the usage of String an unnecessary exception to standard object semantics--an exception that everyone has to learn to deal with (usually the hard way). I call it 'unnecessary' because, as far as I can determine, there was no clear benefit to making it an object that would offset the drawbacks. IMNSHO, this was a language design mistake.

Others would take a different tack and argue that including primitives in Java was the real design mistake. There is a case to be made for avoiding primitives and making *everything* in the language an object. I don't have a firm opinion on that either way, but it is an interesting argument.

Re: java.lang.String is NOT immutable

I'd come across something similiar with altering the classloader at runtime. I'd never thought about other uses. Thanks for the info. Ignore the others.

Re: java.lang.String is NOT immutable

What's with all the nitwits telling him about SecurityManager when he mentions it right in the post?!

Re: java.lang.String is NOT immutable

for wht perpose they keep the String immutable ?

Re: java.lang.String is NOT immutable

for wht perpose they keep the String immutable ?

Re: java.lang.String is NOT immutable

for wht perpose they keep the String immutable ?

Re: java.lang.String is NOT immutable

for wht perpose they keep the String immutable ?

Re: java.lang.String is NOT immutable

for purpose of save usage as HashMap key

Re: java.lang.String is NOT immutable

Good attempt, but it may be better if you change the subject and finally make a conclusion that by *tweaking* you can make it immutable. Since a newbie would be confused with all the stuff and conclude that the String is mutable.

Re: java.lang.String is NOT immutable

lol

Re: java.lang.String is NOT immutable

Although we are discussing Java, this may give you some insite: "A String is called immutable because its value cannot be modified once it has been created. Methods that appear to modify a String actually return a new String containing the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class." Summing this up, this is the same case as with Java. Source: msdn.microsoft.com/library/en-us/ cpref/html/frlrfsystemstringclasstopic.asp