Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"==" in case of String concatenation in Java

Tags:

java

string

String a = "devender";
String b = "devender";
String c = "dev";
String d = "dev" + "ender";
String e = c + "ender";

System.out.println(a == b);     //case 1: o/p true

System.out.println(a == d);     //case 2: o/p true

System.out.println(a == e);     //case 3: o/p false

a & b both are pointing to the same String Literal in string constant pool. So true in case 1

String d = "dev" + "ender";

should be internally using something like:

String d = new StringBuilder().append("dev").append("ender").toString();

How a & d are pointing to the same reference & not a & e ?

like image 947
Dev Avatar asked Oct 09 '22 10:10

Dev


People also ask

Can you use a double in string concatenation?

The “+” operator with a String acts as a concatenation operator. Whenever you add a String value to a double using the “+” operator, both values are concatenated resulting a String object.

How does == work for strings in Java?

In String, the == operator is used to comparing the reference of the given strings, depending on if they are referring to the same objects. When you compare two strings using == operator, it will return true if the string variables are pointing toward the same java object. Otherwise, it will return false .

What is the string concatenation symbol in Java?

Using the + operator is the most common way to concatenate two strings in Java. You can provide either a variable, a number, or a String literal (which is always surrounded by double quotes). Be sure to add a space so that when the combined string is printed, its words are separated properly.


1 Answers

Four things are going on:

  1. (You clearly know this, but for lurkers) == tests to see if the variables point to the same String object, not equivalent strings. So even if x is "foo" and y is also "foo", x == y may be true or false, depending on whether x and y refer to the same String object or different ones. That's why we use equals, not ==, to compare strings for equivalence. All of the following is just meant to explain why == is sometimes true, it's not a suggestion to use == to compare strings. :-)

  2. Equivalent string constants (strings the compiler knows are constants according to various rules in the JLS) within the same class are made to refer to the same string by the compiler (which also lists them in the class's "constant pool"). That's why a == b is true.

  3. When the class is loaded, each of its string constants is automatically interned — the JVM's string pool is checked for an equivalent string and if one is found, that String object is used (if not, the new String object for the new constant is added to the pool). So even if x is a string constant initialized in class Foo and y is a string constant initialized in class Bar, they'll be == each other.

    Points 2 and 3 above are covered in part by JLS§3.10.5. (The bit about the class constant pool is a bit of an implementation detail, hence the link to the JVM spec earlier; the JLS just speaks of interning.)

  4. The compiler does string concatenation if it's dealing with constant values, so

    String d = "dev" + "ender";
    

    is compiled to

    String d = "devender";
    

    and "devender" is a string constant the compiler and JVM apply points 2 and 3 above to. E.g., no StringBuilder is used, the concatenation happens at compile-time, not runtime. This is covered in JLS§15.28 - Constant Expressions. So a == d is true for the same reason a == b is true: They refer to the same constant string, so the compiler ensured they were referring to the same string in the class's constant pool.

    The compiler can't do that when any of the operands is not a constant, so it can't do that with:

    String e = c + "ender";
    

    ...even though code analysis could easily show that the value of c will definitely be "dev" and thus e will definitely be "devender". The specification only has the compiler do the concatenation with constant values, specifically. So since the compiler can't do it, it outputs the StringBuilder code you referred to and that work is done at runtime, creating a new String object. That string isn't automatically interned, so e ends up referring to a different String object than a does, and so a == e is false.

    Note that as Vinod said, if you declared c as final:

    final String c = "dev";
    

    Then it would be a constant variable (yes, they're really called that) and so §15.28 would apply and the compiler would turn

    String e = c + "ender";
    

    into

    String e = "devender";
    

    and a == e would also be true.

Just to reiterate: None of which means we should use == to compare strings for equivalence. :-) That's what equals is for.

like image 84
T.J. Crowder Avatar answered Oct 17 '22 20:10

T.J. Crowder