Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 452
Tariq Ayman Avatar asked Jul 23 '13 21:07

Tariq Ayman


2 Answers

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".

like image 97
rgettman Avatar answered Oct 17 '22 12:10

rgettman


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";
like image 3
Lee Meador Avatar answered Oct 17 '22 12:10

Lee Meador