15

Possible Duplicate:
intern() behaving differently in Java 6 and Java 7

On this blog I found interesting String puzzles:

--- Quote ---

String te = "te", st = "st";
//"test".length();
String username = te + st;
username.intern();
System.out.println("String object the same is: " 
   + (username == "test"));

prints under Java 7 update 7.

String object the same is: true

but uncomment the "test".length(); line, or run with Java 6 and it prints

String object the same is: false

--- EoQ ---

Being honest I don't understand why the outputs are different. Could you please explain me what's the cause of such behaviour?

Community
  • 1
  • 1
Adam Sznajder
  • 9,108
  • 4
  • 39
  • 60

2 Answers2

14

You need to assign the interned string back to username:

String username = te + st;
username = username.intern();

In which case both codes will output true.

Here is another interesting example:

final String te = "te", st = "st";
"test".length();
String username = (te + st);
System.out.println("String object the same is: " + (username == "test"));

prints true as well, because te and st are marked as final. So username becomes a compile time constant and is interned automatically.

EDIT

As several people pointed out your code prints false with Java 6, even when the "test".length line is commented out.

This is due to one of the changes introduced in Java 7:

in JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application.

One consequence is that the code you posted has different outputs in Java 6 and 7 (see example at the bottom of the bug report).

assylias
  • 321,522
  • 82
  • 660
  • 783
5

Please check answer of Does String.intern() change reference of Original String

It is not the String which is changed, but the object which is used for "test" which is changed.

So in your case if "test" is defined first which means if you do first"test".length(); then "test" is in string pool so first result is false.

Now if you comment this line then after calling username.intern(); "test" gets added to string pool now the next "test" which you are using for comparison gets allocated same object which was put by username.intern(); method. Hence it is true

so

Commented //"test".length(); -> True
Un Commented "test".length(); --> False
Community
  • 1
  • 1
Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72