巴扎黑2017-04-18 10:08:31
I ran the above code using JDK6 and JDK7 respectively, and the results are as follows:
JDK6: false, false
JDK7: false, false
It is not true or false as the questioner said. I think there are two main reasons:
The string "java" is special, it exists fixedly in the constant pool
Hence the code
String str1 = new StringBuilder("ja").append("va").toString();
System.out.println(str1.intern() == str1);
str1.intern() returns an object in the constant pool, so it is not the same object as str1 on the heap.
The "python" string already appears in the code, so it will be added to the constant pool.
In the second part of the code, because the literal constant "python" appears, it will be added to the constant pool.
And:
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2);
The empty string "" is added to the string "python", so it is equivalent to not adding a new string constant, and str2.intern() still returns the object in the constant pool.
In fact, the above question can be extended, for example:
// 1
String str1 = new StringBuilder("ja").append("va1").toString();
System.out.println(str1.intern() == str1); // true
// 2
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2); // false
I just changed the first part of the code "StringBuilder("ja").append("va")" to "StringBuilder("ja").append("va1")". Will this change have any different results? ?
Let’s take a look at the results of running under JDK6 and JDK7:
JDK6: false, false
JDK7: true, false
Why are the running results of JDK6 and JDK7 different?
In fact, this involves different implementations of the intern() method in different JDKs:
In JDK6 and previous JDKs:
intern() 方法会把首次遇到的字符串实例 **复制** 到永久代中, 然后返回永久代中的实例.
For JDK7 and above:
当遇到第一次出现的字符串时, intern() **不再复制实例**, 而是在常量池中记录首次出现的实例的引用, 并且 intern() 返回的是此实例引用.
Based on the difference between the intern() methods of JDK6 and JDK7, we know the example:
// 1
String str1 = new StringBuilder("ja").append("va1").toString();
System.out.println(str1.intern() == str1); // true
// 2
String str2 = new StringBuilder("python").append("").toString();
System.out.println(str2.intern() == str2); // false
The reason why different results are returned in different JDKs:
In JDK6, "java1" is the first string constant that appears, so it will be copied to the constant pool. The intern() method returns the string constant in the constant pool. object, so it is not the same as str1 on the heap.
In JDK7, "java1" is the first string constant that appears, but the intern() method only adds a reference to this object to the constant pool. It does not copy a new object to the constant pool like JDK6, so the reference returned by the intern() method is actually equal to the original str1.