class Test {
public static void main(String...args) {
String s1 = "Good";
s1 = s1 + "morning";
System.out.println(s1.intern());
String s2 = "Goodmorning";
if (s1 == s2) {
System.out.println("both are equal");
}
}
}
This code produces different outputs in Java 6 and Java 7.
In Java 6 the s1==s2
condition returns false
and in Java 7 the s1==s2
returns true
. Why?
Why does this program produces different output in Java 6 and Java 7?
The result code dependents runtime:
If you write like this:
the reason is ' ldc #N ' (Load string from constant pool) and String.intern() both will use StringTable in hotspot JVM. For detail I wrote a pool english article: http://aprilsoft.cn/blog/post/307.html
In jdk6:
String s1="Good";
creates a String object "Good" in constant pool.s1=s1+"morning";
creates another String object "morning" in constant pool but this time actually JVM do:s1=new StringBuffer().append(s1).append("morning").toString();
.Now as the
new
operator creates an object in heap therefore the reference ins1
is of heap not constant pool and theString s2="Goodmorning";
creates a String object "Goodmorning" in constant pool whose reference is stored ins2
.Therefore,
if(s1==s2)
condition is false.But what happens in jdk7?
there are mainly 4 ways to compare string:
Let's omit unnecessary details from the example:
Let's consider
String#intern
as a black box. Based on a few test cases run, I would conclude that implementation is as following:Java 6:
if the pool contains object equals to
this
, then return reference to that object, else create new string (equal tothis
), put to the pool, and return reference to that created instance.Java 7:
if the pool contains object equals to
this
, then return reference to that object, else putthis
to the pool, and returnthis
.Neither Java 6 nor Java 7 breaks the contract of the method.
It seems that new intern method behavior was a result of the fix of this bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6962931.
Whenever you are comparing between two String, don't use
==
and useeqauls()
becaue you are comparing objects not references:FIRST CASE:
In the first code snipped you are actually adding three Strings in the Pool of Strings. 1. s1 = "Good"
2. s1 = "Goodmorning" (after concatenating) 3. s2 = "Goodmorining"
While doing if(s1==s2), the objects are same but reference as different hence it is false.
SECOND CASE:
In this case you are using s1.intern(), which implies that if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.