3

Lets see we have 2 references to instances of a user-defined class, a and b in Java. Can there ever be a situation where a == b but a.equals(b) return false?

Vince
  • 79
  • 3

8 Answers8

8

Sure! The implementation of .equals() is completely up to the class, so I could write:

class Foo
    public boolean equals(Object other) {
        return false;
    }
}

Now it doesn't matter what two instances you pass — even the exact same instance twice — I'm always going to say they're not equal.

This particularly setup is silly, but it illustrates that you can get a false result from .equals() for the same object twice.

Note that we're talking here about what can happen, not what should. No class should ever implement a .equals method that claims an object isn't equal to itself. For trusted code, it's reasonable to assume this will never happen.

VoteyDisciple
  • 37,319
  • 5
  • 97
  • 97
  • 6
    However, it's _not_ possible if the `equals` contract is obeyed. – Louis Wasserman Jul 07 '12 at 21:00
  • That's an important point; I've edited my answer to include that clarification. While technically possible, anyone who actually built such a thing deserves to have their programming license revoked. – VoteyDisciple Jul 08 '12 at 02:50
5

if a == b then a.equals(b) should be true. And if a.equals(b) then maybe a == b but not necessarily.

The == operator just test if both are referencing the same object. While equals executes a logic that you implemented. The last one can be overridden the first one is an operator from the language, and such as cannot be overridden in Java.

References

what is the difference between == operator and equals()? (with hashcode() ???)

From java.lang.Object documentation:

The equals method implements an equivalence relation on non-null object references:

  1. It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  2. It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  3. It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  4. It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  5. For any non-null reference value x, x.equals(null) should return false.
Community
  • 1
  • 1
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
4

Yes, just overload equals to do something silly. e.g.

class Foo {
    @Override
    boolean equals(Object rhs) { return false; }
}
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
3

It is obviously possible to write code that does this, as other answers have pointed out.

However, it is also always a logical error in the code, since it violates the implicit general contract of the equals() function.

An object should always be equal to itself, so if (a==b) then a.equals(b) should always return true.

mikera
  • 105,238
  • 25
  • 256
  • 415
2

Ya we can overload the .equals function to give the desired output. but there is no case where == returns true while .equals returns false.

class s {
    int a;
}

class dev {
    public static void main(String args[]) {
        s a = new s();
        s b = new s();
        System.out.println(a == b);
        System.out.println(a.equals(b));
    }
}
Output
false
false
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
cdev
  • 93
  • 8
0

Yes, easily:

public class Wrong{
    public boolean equals(Object other) 
    {
    return false;
    }
}

Of course, this completely breaks the normal rules for implementing .equals() - see the Javadocs - but there's nothing to stop you other than good sense.

DNA
  • 42,007
  • 12
  • 107
  • 146
0

The equals method can be overridden in order to provide custom functionality other than the typical == method. Also, some types such as Strings will not return true when using the == method. You have to use .equals or .compareTo (equal when returns 0).

This should provide some additional help

Nikson Kanti Paul
  • 3,394
  • 1
  • 35
  • 51
zarazan
  • 1,164
  • 10
  • 13
0
package com.stackOverFlow;

import java.util.Date;

public class SampleClass {

public static int  myint = 1;
private SampleClass() {
};

public Integer returnRandom() {
    return myint++;
}

private static SampleClass _sampleClass;

public static SampleClass getInstance() {

    if (_sampleClass == null) {
        _sampleClass = new SampleClass();
    }
    return _sampleClass;
}

@Override
public boolean equals(Object other) {
    if (this.returnRandom().equals(((SampleClass) other).returnRandom())) {
        return true;

    }
    return false;
}

}



package com.stackOverFlow;

public class Run {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    SampleClass a = SampleClass.getInstance();
    SampleClass b = SampleClass.getInstance();
    if(a==b){
        System.out.println("references are same as they are pointing to same object");
        if(!a.equals(b)){
            System.out.println("two random number Instance will never be same");
        }
    }

}

}

You can understand this by Practical example. where a singeleton class will always return you same reference, and you can override equals method to get something that is not class variable. example a value from database at two particular time , or a random number. Hope that clears your case

ManMohan Vyas
  • 4,004
  • 4
  • 27
  • 40
  • This is just a wall of poorly-formatted code and as it is currently written it needs at least two reads for someone who already knows Java to understand. – Joey Jul 08 '12 at 08:22
  • @Joey I am new to SO, will take care next time. thanks for pointing that out – ManMohan Vyas Jul 08 '12 at 09:45