So much confusion in your question and lack of coherence. You write:
We can compare two objects by overriding the equals/hashcode method in the respective class
No, you don't. You compare two objects when you are executing something like, for example:
String firstString = "asdf";
int result = firstString.compareTo("asdff");
You "compare" when you call the compareTo
method on an object of a class that implements Comparable
(firstString
), passing another object ("asdff"
) as the actual parameter of the method. That's it, it's just a matter of names (the names of the types -- classes -- and the names of the methods).
For what concerns the difference between the equality operator (==) and the equals method, again, it's just a matter of definitions. The rules are defined here https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21
Even if we found out that the two objects have same values of all attributes, does this really mean anything beyond that?
What objects? What types are these objects? What type are their attributes? It all depends on how they are implemented. The question is very ambigous but I would say that the answer is no anyway. Equality, in the context of a Java program (or any other language), does not mean anything beyond what the language specifications, and the code, define.
I suppose they will also hold two different memory locations, isn't it?
Example (If you do not understand the "assert" thing, check JUnit out. It just means "this has to be true/false"):
@Test
public void testCrazy()
{
Object firstObject = new Object();
// now I have a reference on the stack (firstObject) that points to some memory
// location on the heap that holds some bytes representing an Object instance
Object secondObject = new Object();
// now I have another reference pointing to a DIFFERENT location on the
// heap
boolean equalReferences = (firstObject == secondObject);
// equalReferences is expected to be false
assertFalse(equalReferences);
// look, I make the first reference point to the locations held by the
// second one (tha is what = does if applied to references)
firstObject = secondObject;
// now the 2 references are expected to pass the equality operator test
assertTrue(firstObject == secondObject);
// what if I override equals in a completely nonsense way?
firstObject = new Object(){
@Override
public boolean equals(Object obj)
{
// no matter what, it always returns false.
// does it make sense? Probably not in our common sense, but the
// compiler won't complain
return false;
}
};
secondObject = firstObject;
// now they do point to same same memory location, in fact
assertTrue(secondObject == firstObject);
// but if I call the overriden equals method:
assertFalse(firstObject.equals(secondObject));
// it is still failing even if I call equals on firstObject itself:
assertFalse(firstObject.equals(firstObject));
}