2
public class First
{
    public static void main(String[] args)
    {
        String str1="Hello ",str2="World",str3="Hello World";
        System.out.println(str3==("Hello "+"World")); //Prints true
        System.out.println(str3==("Hello "+str2));  //Prints false
    }
}

The reason of the above is given in JLS-

• Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.

• Strings computed by concatenation at run time are newly created and therefore distinct.

What I wanted to ask is- Why the strings which are computed at run time differ from those which are computed at compile time? Is it because of the memory allocation,one is allocated memory in heap and one in String pool or there is some other reason?Please clarify.

trincot
  • 317,000
  • 35
  • 244
  • 286
Frosted Cupcake
  • 1,909
  • 2
  • 20
  • 42
  • 1
    String literals are like `str = "hello";` they are taken from String pool... But newly created means like `str = new String()`... So it will be a different object... – Codebender Jul 09 '15 at 05:33
  • @Codebender-But why they differ? – Frosted Cupcake Jul 09 '15 at 05:35
  • Because they are not [internalized](http://stackoverflow.com/questions/10578984/what-is-string-interning). – YoYo Jul 09 '15 at 06:33
  • For str2, add final keyword and initialized within declaration , then it will print `true` for the second print statement. A constant variable - is a final variable of primitive type or type String that is initialized with a constant expression. Constant Expression - https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28 – Yuresh Karunanayake May 04 '21 at 08:20

4 Answers4

2

The compiler can't know what str2 contains because it would have to execute the code to know the contents of str2 when you are concatenating it with "Hello " (it could make some optimizations and inline it, since it doesn't change, but it doesn't do it).

Imagine a more complex scenario where str2 is something that a user typed in. Even if the user had typed "World" there was no way the compiler could've known that.

Therefore, it can't perform the comparison str3 == "Hello World" using the same "Hello World" from the constant pool that's assigned to str3 and used in the first comparison.

So the compiler will generate the concatenation by using StringBuilder and will end up creating another String with value Hello World, so the identity comparison will fail because one object is the one from the constant pool and the other one is the one that was just created.

xp500
  • 1,426
  • 7
  • 11
1

You should use equals when comparing Objects and not the == operator.

M. Shaw
  • 1,742
  • 11
  • 15
  • @M.Shaw-that I know,I want an explaination for the points mentioned in the JLS given above – Frosted Cupcake Jul 09 '15 at 05:34
  • 1
    @RajMalhotra As the JLS states a `String` created at runtime is a newly created `Object`. Thus `==` will return true if the address is the same. On the other hand `Strings` created at compile time are treated as literals - thus `==` would return true. – M. Shaw Jul 09 '15 at 05:36
0

Strings are immutable in Java. So, when you concatenate two strings, a third one is created at runtime to represent the concatenated value. So using == returns false as both arguments are pointing to different instances of String object.

For compile time scenario, due to compiler optimization, the concatenated string is already created, and at runtime, boht arguments of == are being represented by same instances. Hence, == returns true as both arguments point to same instance (reference).

Wand Maker
  • 18,476
  • 8
  • 53
  • 87
0

The compiler recognizes that constants won't change and if you are using the + operator, will concatenate them in the compiled code. That's why in first case it will run the execution as str3==("HelloWorld") since "Helloworld" literal is already present in the string pool they both will point at the same location in the String pool it will print true .

In case of str3==("Hello"+str2),the compiler won't check that str2 has World in it, it will consider it as a variable that can have any value so at run time they will create a new string variable which point to different HelloWorld than the str3 in the string pool, so it will print false.