Home > OS >  Why do these three comparisons give different results?
Why do these three comparisons give different results?

Time:06-11

Why do these three comparisons give different results?

public class Adana {
    public static void main(String[] args) {

        String word1 = "Adana", word2 = "ana";
        
        System.out.println(word1 == "Adana"); // true
        System.out.println(word1 == ("Ad" "ana")); // true
        System.out.println(word1 == ("Ad" word2)); // false
    }
}

CodePudding user response:

Why do these three comparisons give different results?

The Java == operator on (2) reference operands tests for reference equality. In these cases, the difference comes down to different semantics of the respective operand expressions.

The first and second print true because the JLS states that only one String object will exists corresponding to any string literal or string-valued constant expression. Therefore you are comparing the same object / reference.

JLS 15.29:

"Constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern."

The third prints false because the JLS states that a non-constant string concatenation produces a new String object. Therefore you are comparing different objects / references.

JLS 15.18.1

"The String object is newly created (§12.5) unless the expression is a constant expression (§15.29)."


Having said that, if you use == to test / compare Java strings, your code is liable to be fragile. Correctness will depend on the origin of the strings. Under most circumstances you should use str1.equals(str2) to compare strings.

See: How do I compare strings in Java?

CodePudding user response:

The == operator, at least when used for objects (and strings are a kind of object), doesn't do what you think it does.

It tests for reference identity - are the 2 object pointers pointing at the exact same object. It does not test if the object(s) pointed at contain the same value.

"Ad" "Ana" will make a new string object with the value "Adana". But it's not the same object. Except, if you write it out literally exactly like that, the compiler will just make that "Adana" for you - it knows at compile time.

The reason "Adana" == "Adana" (or in your case, `word1 == "Adana") is because string literals in a class file are created once and then all usages of it re-use the same object. In fact, due to interning, this even happens between classes.

The reason "Ad" word2 doesn't work anymore is because the compiler doesn't "pre-compute" this, so it's a new string, and hence, no reference identity.

Do not worry about whether or not the compiler can suss it out: Just know that == compares reference identity, and for strings, 'reference identity' is not something you should ever be caring about.

If you want value comparison, use .equals:

System.out.println(word1.equals("Ad" word2));

That'll print true as expected.

  •  Tags:  
  • java
  • Related