0
public class Test { 
    public static void main(String[] args) 
    { 
        String s1 = "HELLO";
        String s2 = "HELLO";

        System.out.println(s1 == s2);  // true
    }  
} 

But when I use :

public class Test { 
    public static void main(String[] args) 
    { 
        String s1 = new String("HELLO");
        String s2 = new String("HELLO");

        System.out.println(s1 == s2); // false
    } 
} 

Can anybody please explain the difference here? Thankyou!

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • 1
    https://www.soner.dev/java/Difference-between-equality-operator-equals-method.html – Soner from The Ottoman Empire Jan 04 '20 at 15:42
  • 1
    The question is, in fact, not a duplicate of https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java. OP is well aware of the semantical differencde between `==` and `.equals(...)`. – Turing85 Jan 04 '20 at 15:53
  • @Turing85 I have edited the question a bit, I had another doubt with final keyword with Strings – Gagan Ganapathy Ajjikuttira Jan 04 '20 at 15:59
  • 1
    Re your edit: don't ask multiple different questions at the same time. But the simple answer is that variables declared with `final` can be (and are, in this case) constant expressions; and string constant expressions are always put into the string pool. – Andy Turner Jan 04 '20 at 15:59
  • 2
    I rolled back your edit, see [ask one question per post](https://meta.stackexchange.com/q/222735) for reasoning behind it. But regarding final strings see [Comparing strings with == which are declared final in Java](https://stackoverflow.com/q/19418427) – Pshemo Jan 04 '20 at 16:00
  • Sorry for edit ! was really stuck on that one! – Gagan Ganapathy Ajjikuttira Jan 04 '20 at 16:00

7 Answers7

4

In the first example

String s1 = "HELLO";
String s2 = "HELLO";

the values of s1 and s2 are compile-time constants. Thus, the compiler does only generate a single String-object, holding the value "HELLO" and assings it to both s1 and s2. This is a special case of Common Subexpression Elimination, a well-known compiler optimization. Thus s1 == s2 returns true.

In the second example, two different Strings are constructed explicitly through new. Thus, they have to be separate objects per the semantics of new.

I created an Ideone demo a while back that highlights some cases that show this behaviour.

You can enforce that the same String is return by using String::intern():

String s1 = new String("HELLO").intern();
String s2 = new String("HELLO").intern();
System.out.println(s1 == s2); // will print "true";

Ideone demo

Turing85
  • 18,217
  • 7
  • 33
  • 58
3

In case of String literal,before creating new Object in String Constant Pool ,JVM will check already same Object persist in SCP area or not if yes it will point to same object instead of creating new Object.Hence, below code s1 == s2 is true

    String s1 = "HELLO";
    String s2 = "HELLO";

    System.out.println(s1 == s2);  // true

but we are creating new object by using new keyword, it will create object in heap area, hence s1 and s2 are pointing to two different object, hence it is return false

Sarjit
  • 799
  • 7
  • 9
1

== tests for reference equality (whether they are the same object).

.equals() tests for value equality (whether they are logically "equal").

from here How do I compare strings in Java?

Sagar Devkota
  • 1,295
  • 3
  • 12
  • 25
1

== compares the objects reference pointer. When 2 objects are same exact object it will be true.

Instantiating a string using double quotes uses the string pool, creates a string once and reuses it.

Instantiating a string wit new always creates a brand new string.

Salim
  • 2,046
  • 12
  • 13
0

== tests for reference equality (whether they are the same object).

First Case

System.out.println(s1 == s2);  // true

Because you are comparing literals that are interned by the compiler and thus refer to the same object. 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 - are "interned" so as to share unique instances, using the method String.intern.

Second Case

System.out.println(s1 == s2); // false

You are comparing the Object reference which is different so you are getting false.

Please check https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28

dassum
  • 4,727
  • 2
  • 25
  • 38
0

i first case u comparing two strings with its ASCII values. thats why...//true and in second case you are comparing two functions/methods. thats why... //false

Mr.Geeky
  • 45
  • 7
0

the first one is true because s1 and s2 refer to the same string literal in the method area, the memory references are the same. ( == checks just the references in string). when the same string literal is created more than once, only one copy of each distinct string value is stored. the second one is false because s1 and s2 refer to two different objects in the heap. different objects always have different memory references.