简体   繁体   中英

Using intern in java Strings

I am trying to understand Java's String class but I am having a hard time understanding the situation described below.

Consider the following example snippet:

String x = new String("Hey");
String y = "Hey";

If I use bool = y == x.intern(); the variable bool will equal true .

My question is:

When I make a declaration like this:

String b = "h";
String a = b.intern + "ey";
boolean x = a == "hey";

x 's value would be false but when I make a = (b + "ey").intern(); x 's value will be true .

Why won't x = true in the second example? Is it because the declarations in the first example not alike? If yes what are the differences?

With your first example:

String y = "Hey";

Java automatically interns string literals such as this ( JLS section 3.10.5 ):

Moreover, a string literal always refers to the same instance of class String. This is because 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.

So when you call x.intern() , you get the interned copy of "Hey" , so they are the same object and == returns true .

But in the second example, b.intern() is a method call that is evaluated at runtime, and Java's concatenation operator will return a new String (not interned), which is a different object than the string literal "hey" (interned already), so == returns false (different objects).

EDIT

To clear up what happens with the string concatenation, turn to JLS Section 15.18.1 :

The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.

The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).

But, b.intern() + "ey"; is not a compile-time constant expression, so the resultant String object has not been interned, and == will detect that it's a different object than the interned "hey" .

This one creates a string and stores it:

String a = b.intern() + "ey";

This one creates a string, interns it and stores the interned version:

String a = (b + "ey").intern();

All interned strings with the same content are ==

All string literals (strings supplied in the form "hey") are interned by the compiler internally.

Strings that are not interned but have the same content are only equal() and not ==

For posterity, one more ... where the compiler optimizes out the + resulting in "hey" and interns it just as it would the string literal "hey"

String a = "h" + "ey";

Java concatenates String s by using a StringBuilder :

b.intern() + "ey" turns into something similar to
new StringBuilder(b.intern()).append("ey").toString() . This creates a new String , so it will not be == to "hey" .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM