1

As I have understood, whenever we create a String literal, the pool is checked for any existing String with the same value. If it exists, a reference to the same is returned. Otherwise a new literal is created.

From this, I understand that pool only contains non-duplicate String literals.

But I am confused by the output of the following code:

String str1 = "Hello World";
String str2 = "Hello";
String str3 = str2+" World";
System.out.println(str3);
System.out.println(((str1 == str3) ? "equal":"unequal"));`

Since str3 is evaluating to "Hello World" which already exists in the pool pointed to by str1, a reference to the same should be assigned to str3 and hence str1 and str3 should be equal.

But the code is showing them as unequal. Would appreciate if someone can explain.

Gaël J
  • 11,274
  • 4
  • 17
  • 32
  • Strings in Java are objects. Doing an == will compare memory addresses rather than the content of the Strings. You should use the isEqual method for that. – Jacobo Aug 02 '21 at 20:13
  • @Jacobo, that's what OP wants to compare references – Gaël J Aug 02 '21 at 20:14
  • @Jacobo The OP _wants_ to compare object references in this example. – GriffeyDog Aug 02 '21 at 20:14
  • Java created an internal pool for strings a version or two back, but that's hidden from you. What you're testing is object equality. Under the covers str1 and str3 are pointing to the same item in a pool, but are different objects. If you go deep in the weeds, your objects are essential pointers to pointers. – Ryan Aug 02 '21 at 20:14
  • 1
    `str3` is not a literal, it's the result of a computation. Plus I'm not sure there's any guarantee that the "string pool" is always used, it's an optimization on which you should never rely from your code. – Gaël J Aug 02 '21 at 20:16
  • 1
    Try making `str2` `final` and see the difference. – Jesper Aug 02 '21 at 20:17
  • 2
    [“==” in case of String concatenation in Java](https://stackoverflow.com/q/34509566) – Pshemo Aug 02 '21 at 20:22
  • 2
    Does this answer your question? ["==" in case of String concatenation in Java](https://stackoverflow.com/questions/34509566/in-case-of-string-concatenation-in-java) – Gaël J Aug 02 '21 at 20:28

4 Answers4

8

str2 + " World" is not a constant expression, so it is not interned. If str2 were final or it were directly written as "Hello" + " World", then the value would be interned.

§3.10.5. String Literals:

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.

See also: §15.28. Constant Expressions

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
2

When you concatenate the strings, you're creating a new string which is different from the one in the pool.

If you call the method intern() then you'll get the expected behavior.

jshell> var a = "hello"
a ==> "hello"

jshell> var b = " world"
b ==> " world"

jshell> a + b == "hello world"
$3 ==> false

jshell> (a + b).intern() == "hello world"
$4 ==> true
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
1

I agree with @Unmitigated

When you are writing

String str3 = str2+" World";

You are in fact creating a string that cannot be known before runtime (or maybe with compiler optimisations, but that's not the point). So the string is considered to be unique

That's the reason why each string should be compared with equals method and never with "=="

GiZeus
  • 86
  • 3
0

As I have understood, whenever we create a String literal, the pool is checked for any existing String with the same value.

The key word is "literal".

String str2 = "Hello";
String str3 = str2+" World";

"Hello" is a string literal.
" World" is a string literal.
str2 + " World" is an expression that concatenates two string values.

A "literal" literally appears as itself in the source code.

It would not be an optimization if the result of every string operation needed to check the literal pool to see if that string had ever appeared before. The overhead is acceptable at compile time, since that's a one-time cost.

iggy
  • 1,328
  • 4
  • 3