Hi,
>From 1.5 and on, does java automatically intern strings?
During a recent team discussion, we thought we read somewhere that
this was added to 1.5 as default behaviour, but we were not sure. By
automatically interning I mean that if you have String a = new
String("ABC") then
String str = new String("ABC")
is equivalent to
String str = a.intern();
Thus far, we have found nothing to say that this was added.
Thanks in advance for your input.
Eric Sosman - 26 Oct 2007 22:51 GMT
pedro.checo@ubs.com wrote On 10/26/07 17:40,:
> Hi,
>
[quoted text clipped - 14 lines]
>
> Thanks in advance for your input.
Why not just try the experiment?
String s1 = "ABC";
String s2 = new String("ABC");
System.out.println(s1 == s2);
For extra amusement, you could check a few other things:
System.out.println(s1 == s1.intern());
System.out.println(s2 == s2.intern());

Signature
Eric.Sosman@sun.com
pedro.checo@ubs.com - 26 Oct 2007 23:02 GMT
> pedro.ch...@ubs.com wrote On 10/26/07 17:40,:
>
[quoted text clipped - 32 lines]
>
> - Show quoted text -
Good point. I should have been more specific. If that is not the
default behaviour, then is there a flag (or any other way) to make it
so? We'd have to change a legacy library in order to take advantage of
String.intern() and would like to avoid making code changes unless
absolutely necessary.
Eric Sosman - 26 Oct 2007 23:23 GMT
pedro.checo@ubs.com wrote On 10/26/07 18:02,:
>>pedro.ch...@ubs.com wrote On 10/26/07 17:40,:
>>
[quoted text clipped - 28 lines]
> String.intern() and would like to avoid making code changes unless
> absolutely necessary.
I'm not a language lawyer, but I think the `new'
operator is *required* to produce a brand-new object
distinct from all existing objects. Check the Java
Language Specification if you want to find out for
sure.
... but what are these changes you contemplate,
and how do you propose to "take advantage" of interned
Strings? If all Strings were in fact interned so that
`s1.equals(s2) == (s1 == s2)' always held, you could
get away with using == instead of .equals(). But the
legacy library would still get the right answer with
.equals(), just as it always did, and it would not be
"absolutely necessary" to change it. So what's up?

Signature
Eric.Sosman@sun.com
kohlerm - 26 Oct 2007 23:27 GMT
Hi,
> pedro.ch...@ubs.com wrote On 10/26/07 18:02,:
[snip]
> sure.
>
[quoted text clipped - 11 lines]
>
> - Zitierten Text anzeigen -
knowing when Strings are interned and when new copies of the
underlying char[] is very important to avoid consuming too much
memory.
Check my blog at https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/5095
Regards,
Markus
Patricia Shanahan - 26 Oct 2007 23:39 GMT
> Hi,
>
[quoted text clipped - 20 lines]
> memory.
> Check my blog at https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/5095
Your blog seems to be about memory consumption and the sharing of the
underlying char[]. Perhaps you could explain the connection you seem to
see between that and intern?
Patricia
Lew - 27 Oct 2007 00:13 GMT
> knowing when Strings are interned and when new copies of the
> underlying char[] is very important to avoid consuming too much
> memory.
Actually, it probably doesn't make a whole lot of difference except in corner
cases.
As a rule of thumb, the JVM and API are very smart about managing String
literals, although they will be essentially permanent. That shouldn't sweat
your memory consumption unless you have a true crapload of literals.
That leaves String intermediate values and new-allocated instances. API
methods like String.substring() tend to be pretty smart about reusing existing
char [] backing arrays, but it's pretty hard, too, to predict how the
optimizer will handle situations. Inlining, loop unrolling and
common-subexpression refactoring are things it does that I can imagine
affecting String allocation, much less interning.
I suspect that most programs facing memory problems will not find interning to
be much of an issue or much help. I'm also pretty sure that there are times
when it will. And there always come those times when every last drop counts.
My concern is that the real impact on performance of different idioms is so
very often counter-intuitive.

Signature
Lew
A. Bolmarcich - 26 Oct 2007 23:35 GMT
> pedro.checo@ubs.com wrote On 10/26/07 17:40,:
>> Hi,
[quoted text clipped - 26 lines]
> System.out.println(s1 == s1.intern());
> System.out.println(s2 == s2.intern());
For even extra amusement
System.out.println(("A"+"B"+"C") == s1);
Roedy Green - 27 Oct 2007 00:47 GMT
>String str = new String("ABC")
>
>is equivalent to
>
>String str = a.intern();
nope. The very opposite. See http://mindprod.com/jgloss/intern.html

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Owen Jacobson - 27 Oct 2007 01:03 GMT
On Oct 26, 2:40 pm, pedro.ch...@ubs.com wrote:
> Hi,
>
[quoted text clipped - 12 lines]
>
> Thus far, we have found nothing to say that this was added.
It was not.
You have to read between the lines a bit, but the JLS forbids this
optimization if its effects would be detectable. Follow along, if you
will:
1. 15.21.3 states that "At run time, the result of == is true if the
operand values are both null or both refer to the same object or
array; otherwise, the result is false."
2. 4.3.1 states that "An object is a class instance or an array." and
that "A class instance is explicitly created by a class instance
creation expression." The reference for that second statement covers
expressions of the form 'new Type (Arguments)', which implicitly
includes 'new String ("Some literal")'.
Those two statements combine to imply that
String a = new String ("foo");
String b = new String ("foo");
boolean same = (a == b);
will always result in 'same' containing false, eg., that the two
objects are not the same instance.
3. 3.10.5 states, "String literals-or, more generally, strings that
are the values of constant expressions (?15.28)-are "interned" so as
to share unique instances, using the method String.intern," which
doesn't cover new expressions, and the documentation for String.intern
follows this with
"for any two strings s and t, s.intern() == t.intern() is true if
and only
if s.equals(t) is true."
which implies that were strings automatically interned such that 'new
String ("foo")' evaluated to an interned instance of "foo", then
String a = new String ("foo");
String b = new String ("foo");
boolean same = (a.intern () == b.intern ());
would result in 'same' being set to true, since a.equals(b) and the
strings would have been interned.