-2

I wrote the following JAVA code in eclipse,

String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");

The output is

false 
true

why the result is like that, can some explain it to me? as I understand, both of them should be true.

Coinnigh
  • 611
  • 9
  • 17
  • 2
    `String s3 = "a"+"b";` is compiled to `String s3 = "ab";` so it uses the same literal string `"ab"` that you are comparing it to. – khelwood Dec 02 '15 at 15:20
  • 1
    The second example prints `true` because both are pointing to the same string in the [Java String Pool](http://stackoverflow.com/questions/2486191/what-is-the-java-string-pool-and-how-is-s-different-from-new-strings) – GriffeyDog Dec 02 '15 at 15:22

2 Answers2

-1

We do not use == to compare Strings in java. It will compare the object references to system memory.

You have several options:

  • equals
  • equalsIgnoreCase
  • matches (Regex)

In your example you defined two Strings. Both will live in different memory locations. == compares only the reference to that location and will find that it is not the same, since you are calling it on two different Strings.

The second comparison is true because java only added one "ab" to memory, hence it will point to the same location. See: java string pool

showp1984
  • 378
  • 1
  • 2
  • 13
  • I know we can use equals method, but I want to understand why the result is like what I wrote in my question. – Coinnigh Dec 02 '15 at 15:16
-1

String is an Object and thus the value of s1 and all other string-typed variables is actually a reference to the actual value.

== compares by value this means that the references are compared to each other, not the String itself. This comparison: System.out.println(s3 == "ab"); simply evaluates to true due to several optimizations of the compiler and JVM. First the compiler optimizes String s3 = "a" + "b"; to String s3 = "ab";. The JVM itself has a pool for strings that are stored as there as constants (this can be done since strings are immutable in java). This string-literal is then used in the comparison and for the initialization of "ab". So when we replace the variable/constant with the respective references the comparison would look somewhat like this:

if(0xA54B == 0xA54B)...

s2 on the other hand won't get optimized in the same way, due to the usage of s1, thus resulting in false. s2 can only be generated on runtime (theoretically it could be optimized, but java doesn't do it), since it requires the value of s1 and thus isn't a constant. s2 won't be stored in/compared to values in the string-pool on runtime, but will be simply put on the heap outside of the string-pool. This is due to the default java implementation. There are plenty of articles about implicit and explicit interning of strings, so I won't post a link. Cooked down: s2 won't be checked against the string-pool and thus will reference another string-object than s3, which points to a string-object in the pool.

Strings are correctly compared using someString.equals(otherString) (lexicographical comparison).

Paul
  • 13,355
  • 3
  • 19
  • 35