http://kohlerm.blogspot.co.uk/2009/01/is-javalangstringintern-really-evil.html
asserts that String.equals()
uses "=="
to compare String
objects before, according to
http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html
it compares the lengths of Strings, and then the contents.
(By the way, product code strings in a sales catalogue are liable to be all the same length - BIC0417 is a bicycist's safety helmet, TIG0003 is a live adult male tiger -
you probably need all sorts of licences to order one of those. And maybe you better order a safety helmet at the same time.)
So it sounds as though you get a benefit from replacing your Strings with their intern()
version, but you get safety - and readability and standard compliance - -without- using "==" for equals()
in your programming. And most of what I'm going to say depends on that being true, if it is true.
But does String.equals()
test that you passed it a String and not some other object, before using "=="
? I'm not qualified to say, but I would guess not, because overwhelmingly most such equals()
operations will be String to String, so that test is almost always passed. Indeed, prioritising "==" inside String.equals()
implies a confidence that you frequently are comparing the String to the same actual object.
I hope no one is surprised that the following lines produce a result of "false":
Integer i = 1;
System.out.println("1".equals(i));
But if you change i
to i.toString()
in the second line, of course it's true
.
Venues where you might hope for a benefit from interning include Set
and Map
, obviously. I hope that interned strings have their hashcodes cached... I think that would be a requirement. And I hope I haven't just given away an idea that could earn me a million dollars. :-)
As for memory, it's also obvious that that is an important limit if your volume of Strings is large, or if you want the memory used by your program code to be very small. If your volume of -distinct- Strings is very large, then it may be time to consider using dedicated database program code to manage them, and a separate database server. Likewise, if you can improve a small program (that needs to run in 10000 instances simultaneously) by having it not store its Strings itself at all.
It feels wasteful to create a new String and then discard it straight away for its intern()
substitute, but there isn't a clear alternative, except for keeping the duplicate String. So really the execution cost is of searching for your string in the intern pool and then allowing the garbage collector to dispose of the original. And if it's a string literal then it comes intern-ed already anyway.
I am wondering whether intern()
can be abused by malicious program code to detect whether some String and their object references already exist in the intern()
pool, and therefore exist elsewhere in the Java session, when that shouldn't be known. But that would only be possible when the program code is already being used in a trusting way, I guess. Still, it is something to consider about the third-party libraries that you include in your program to store and remember your ATM PIN numbers!