问题
From the javaDocs of String class's intern method :
When the intern method is invoked, 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.
Consider the following use-cases:
String first = "Hello";
String second = "Hello";
System.out.println(first == second);
String third = new String("Hello");
String fourth = new String("Hello");
System.out.println(third == fourth);
System.out.println(third == fourth.intern());
System.out.println(third.intern() == fourth);
System.out.println(third == fourth);
System.out.println(third.intern() == fourth.intern());
System.out.println(third.intern() == first);
String fifth = new String(new char[]{'H','e','l', 'l', 'o'});
String sixth = new String(new char[]{'H','e','l', 'l', 'o'});
System.out.println(fifth == fifth.intern());
System.out.println(sixth == sixth.intern());
String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
String eight = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
System.out.println(seven == seven.intern());
System.out.println(eight == eight.intern());
Can someone please explain why seven == seven.intern()
is true whereas the following are false:
System.out.println(fifth == fifth.intern());
System.out.println(sixth == sixth.intern());
System.out.println(eight == eight.intern());
回答1:
seven is the first time you use the string 'hello2'. Therefor what the intern
does is insert your string to the pool (and also return it). there for it is equal to your seven.
when you work with eight, the string is already in the pool (by running seven.intern()
before, therefor when you do eight == eight.intern()
you will get on the left side of the equation the newly created eight
string, and on the right side the string created by seven from the pool, which are not the same
回答2:
Because when you use the new String()
syntax, you are not taking advantage of the String pool, but creating a new instance of String regardless of whether it is in the pool or not.
Moral of the story.. NEVER use new String()
You are at the mercy of the JVM, which has the choice of making the decision of whether or not an 'internalized' String already exists, or should be internalized. More specifically:
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String. Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
回答3:
pczeus is correct. More info:
fifth is a new string (pool was not checked) that contains the value "Hello". When you intern() it, the return value is fourth (first occurrence of "Hello" being interned), which does not equal fifth.
Same answer for sixth.
seven is the first occurrence of "Hello2" and it does not get interned until you call 'seven == seven.intern()'. Since it gets interned at that moment the return value of intern() is seven.
eight is another new instance of "Hello2". When it gets interned, the return value is seven, which is not eight
回答4:
String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
The literal "Hello2
" will cause an object in the string constant pool to be created. The new String will create a new String object on the heap, with a copy of the content of the object for the literal.
You should never create String object like that, because it's unnecessary and inefficient. When you do System.out.println(seven == seven.intern());
it will print true
.
Now when you do System.out.println(eight == eight.intern());
the string is returned from the string pool as it is already present, hence it will print false
.
来源:https://stackoverflow.com/questions/35933011/string-intern-behaviour