Categories
equality identity java object-comparison

What is the difference between == and equals() in Java?

735

I wanted to clarify if I understand this correctly:

  • == is a reference comparison, i.e. both objects point to the same memory location
  • .equals() evaluates to the comparison of values in the objects

5

  • 57

    yeah, pretty much

    – John Kane

    Sep 22, 2011 at 19:40

  • 11

    Yes, spot on. You can think of .equals() as meaningfully equivalent

    Jul 8, 2013 at 13:30

  • Possible duplicate of How do I compare strings in Java?

    – TylerH

    Jun 22, 2016 at 20:46

  • 29

    A sentence like “both objects point to the same memory location” is sloppy language, which can make understanding more difficult. You mean: “both variables refer to the same object”. Note that a variable is not an object; a variable is a reference to an object. Objects don’t “point to” anything.

    – Jesper

    Feb 8, 2017 at 9:47


  • In C# (and many other languages) the equality operator ( == ) corresponds to the Object.Equals() method. Descendants classes, like String, can define what it means for two strings to be == by overriding the .Equals method. Java cannot do that. The Java String class (and no class in Java) has a way to override == to make it behave the way it should behave. This means you must call .equals() yourself manually.

    – Ian Boyd

    Jul 23 at 20:40


711

In general, the answer to your question is “yes”, but…

  • .equals(...) will only compare what it is written to compare, no more, no less.
  • If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method.
  • If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you’re left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.
  • Always remember to override hashCode if you override equals so as not to “break the contract”. As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.

5

  • if == checks for memory reference then why am I getting this strange behavior in [this][1][1]: docs.google.com/document/d/… I expected output to be true. can clear my confusions

    – JPG

    Jun 14, 2015 at 8:19


  • 4

    @JSK print the values of d1 and d2 and I think you’ll see why you’re returning false.

    – BoDidely

    Jul 29, 2015 at 20:01

  • 2

    @BoDidely I figured it out. It was because all the wrapper classes are immutable.

    – JPG

    Jul 31, 2015 at 20:41

  • The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). <br/> Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes. (docs.oracle.com/javase/7/docs/api/java/lang/…)

    – Abhijeet

    Jul 6, 2016 at 13:20


  • Unrelated: Today I put up a meta question ( meta.stackoverflow.com/questions/372795/… ) regarding good/effective/… “auto” messages when commenting low quality newbie questions. The feedback I received felt pretty much “you are doing the totally wrong thing”. Now I am simply wondering how you look at this? Do you have “generic” messages in your quiver, or do you write solely specific comments in such cases?

    – GhostCat

    Aug 20, 2018 at 18:05

125

With respect to the String class:

The equals() method compares the “value” inside String instances (on the heap) irrespective if the two object references refer to the same String instance or not. If any two object references of type String refer to the same String instance then great! If the two object references refer to two different String instances .. it doesn’t make a difference. Its the “value” (that is: the contents of the character array) inside each String instance that is being compared.

On the other hand, the “==” operator compares the value of two object references to see whether they refer to the same String instance. If the value of both object references “refer to” the same String instance then the result of the boolean expression would be “true”..duh. If, on the other hand, the value of both object references “refer to” different String instances (even though both String instances have identical “values”, that is, the contents of the character arrays of each String instance are the same) the result of the boolean expression would be “false”.

As with any explanation, let it sink in.

I hope this clears things up a bit.

3

  • 1

    so for strings == is reference equals aswell? ie works the same as for other objects?

    – JonnyRaa

    Feb 20, 2014 at 14:12

  • 3

    (Thread necromancy, I know…) For Strings, == is reference equals as well, yes, but it usually works (as in two Strings with the same content will usually be == to each other), because of how Java handles Strings. It won’t always, and it’s certainly bad practice, but it’s a common mistake, particularly from people coming from other languages.

    – Tonio

    Oct 3, 2014 at 22:33

  • 12

    To add on to Tonio’s comment. String build from string literal will be added to something called the String constant pool, e.g. String s1 = "someString"; String s2 = "someString;" both s1 & s2 will share the same reference. s1 == s2 will return true. But if they were constructed via the String constructor, e.g. String s1 = new String("someString"); String s2 = new String("someString"); then they will not share the same reference. s1 == s2 will return false.

    – Gavin

    Nov 15, 2017 at 14:25


71

There are some small differences depending whether you are talking about “primitives” or “Object Types”; the same can be said if you are talking about “static” or “non-static” members; you can also mix all the above…

Here is an example (you can run it):

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

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

You can compare the explanations for “==” (Equality Operator) and “.equals(…)” (method in the java.lang.Object class) through these links:

2

  • 2

    Interesting example. Different perspective from the above answers. Thanks!

    – Andrew

    Mar 11, 2015 at 15:30

  • 1

    Best answer in my opinion, as it’s clearer than the other full-text answers without losing the explanation (if you undertand class and static concepts, of course)

    – Carrm

    Aug 30, 2017 at 9:31