This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
To the best of our knowledge, foo == bar will always evaluate to true, assuming both foo and bar were assigned using equivalent constant string expressions, or using the intern() method on an equivalent string. Even if they're from different classes, classloaders, whatever. The JVM has exactly one string intern pool, outside any classloader, and it retains at most one instance of any given string content.
The only known exception is achieved by reformulating the question a bit and comparing two interned strings which are not in the JVM at the same time. That is, it's possible to load a string into the intern pool, then cause it to be unloaded, then intern another string with the same content, and determine that the new string is different than the original, using System.identityHashCode().
To do this with string constants, this requires you to use one classloader to load a class containing the constant, then make the class and classloader eligible for GC, then hope that GC successfully removes the classloader, class, and interned string, then use a new classloader to load a class with an equivalent constant. This may sound like a rare occurrance, but it can happen quite easily in an environment like a web app server. However since the two interned strings cannot be in the JVM at the same time (else the intern pool would resolve them to a single instance), it's impossible to compare them directly usign either == or equals(), or compareTo() or most other tests that might detect that the instances are different. Accordingly, this doesn't actually affect people very often; it's somewhat similar to debating how many angels can stand on the head of a pin.
"I'm not back." - Bill Harding, Twister
Joined: Jun 14, 2006
Thank you very much for the detailed answer...exactly what I was hoping for.
For better and worse, I'm the kind of coder who needs to know how it works behind the scenes...I don't blindly remember facts very well. So just discussing angles and pin heads leads to a better understanding of both even if the conversation is pointless.
And...this is silly of me...but this is my first Java question ever to break out of 'beginner' so I guess all my time on Java Ranch is beginning to show.
I can see that it could be interesting to know about what's going on with the string pool. But I am surprised how often questions about it come up.
I've been programming Java for about 7 years without ever writing a piece of code that depended on the string pool. And I think that writing a piece of code that depends on the string pool's behaviour is bad; it's far too unobvious, and unobvious code is unmaintainable and rots quickly.
The only feature of the string pool that I allow myself to depend on is that it makes it OK, from a memory consumption point of view, to have several repetitions of the same String literal in my code. But even that is something which one would generally want to avoid; if you're repeating a particular String literal, you might want to assign it to a named constant, so it can be changed in a single place, if it ever needs to change.
Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Joined: Jun 14, 2006
Well, I've been coding Java (like really programming...not school or tinkering) for a whopping two months. I didn't know that two identical string literals compiled into a single item in the string pool until this morning. (I was stunned to see (foo == bar) evaluate to true in the above example.) When I learned this it seemed like 'magic'...and years of programming in other languages has made me very cautious of things that happen magically.
So I came to JR.
So don't fret...I am not going to go out and code string stuff in a manner that would upset you.
Stu [ August 17, 2006: Message edited by: Stu Thompson ]
Originally posted by Mr. C Lamont Gilbert: Only time I use == in my code is between primitives. Even when I have otherwise guaranteed 'equals' equals '=='.
There is a common philsophy among many people who share an interest in the field that using the == operator on reference types implies a type of defect. This can be mathematically expressed, but I'll bet you can also find some articles "out there" from those who claim to be experts.