Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does a.equals(a) return false?

Tags:

java

I was wondering which are the cases where a variable in java could not be equal (using the equals() method) to itself. I am not talking object here but the variable itself (as long as the code compiles and return false when calling equals). The only situation in which it does that I found so far is:

public class A {
    public static void main(String args[]){
        A a = new A();
        System.out.println(a.equals((a = null)));
    }
}

Is there any other case in which a.equals(a) would return false?

EDIT: no overriding of equals() is allowed but you can Modify (cast, inherit) a as much as you want as long as the variable a compare itself in the end.

like image 971
Paiku Han Avatar asked Mar 19 '23 12:03

Paiku Han


2 Answers

It could return false in multithreaded contexts, even with an equals implementation that fulfills the equals contract:

class Test {
    public static final A a = new A();

    public static void main(String... args) throws Exception {
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    a.x += 1;
                }
            }
        }.start();
        Thread.sleep(10);

        System.out.println(a.equals(a));  // <---
    }
}

class A {
    int x;

    @Override
    public boolean equals(Object o) {
        return (o instanceof A) && ((A)o).x == x;
    }
}
false
like image 76
arshajii Avatar answered Apr 06 '23 02:04

arshajii


From the Object documentation of Oracle:

public boolean equals(Object obj)

Indicates whether some other object is "equal to" this one.

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

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.
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.
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.
For any non-null reference value x, x.equals(null) should return false. 

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).

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.

Parameters: obj - the reference object with which to compare. Returns: true if this object is the same as the obj argument; false otherwise.

So coming back to your question and analizing the documentation

It's false when a.equals(null); and when a and b (Objects of the classes A and B respectively) are compared, i.e. a.equals(b) will return false too.

In other cases it's true, because of:

It is reflexive: for any non-null reference value x, x.equals(x) should return true.

It clearly says that: not null reference to x (or a in this case):

a.equals(a); will be true

like image 42
Frakcool Avatar answered Apr 06 '23 04:04

Frakcool