Yes, the default implementation is Object's (generally speaking; if you inherit from a class that redefined equals and/or hashCode, then you'll use that implementation instead).
From the documentation:
equals
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).
hashCode
Answer from Etienne de Martel on Stack OverflowAs far as is reasonably practical, the hashCode method defined by class Object returns distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
Videos
Yes, the default implementation is Object's (generally speaking; if you inherit from a class that redefined equals and/or hashCode, then you'll use that implementation instead).
From the documentation:
equals
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).
hashCode
As far as is reasonably practical, the hashCode method defined by class Object returns distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
From Object in one of the JVM implementations:
public boolean equals(Object object) {
return this == object;
}
public int hashCode() {
return VMMemoryManager.getIdentityHashCode(this);
}
In both cases it's just comparing the memory addresses of the objects in question.
So, as a beginner, I found that comparing objects with the default equals() method actually does almost exactly the same thing like comparing them with ==. In other words, if two variables reference the same object, == will resolve as true and also equals() will resolve as true. But if we have two variables referencing two objects with a different identity but semantically the same (like, hmmm they look same to me! Same variables, etc.!) we actually have to come with our own equals() method and override the Java default method. (And when doing that, why not also override HashCode(), you know).
Now my question is not the typical "why???"(technicaly why it is needed?) but "why???" (why on earth was Java language designed this way)? Why Java does not have e.g. objectsEquals() method that would work for objects comparing all the fields etc. by default?
Why it even has equals() method that works the same as operator ==? In such a universe we could also have methods isTheSame(), isCompletelyTheSame() and thisIsEqual() all doing the same stuff? And also why we are even overriding it? Is it like "Java authors designed this method poorly or too generally, so let us made our better method that does also this and that". Why not create a framework class or our own class or just completely new method like sameObjects() and just use it with our own new beatiful name? Why overriding? Sorry, I am pretending rant, but I am just trying to be a little funny and also as a beginner I do not really understand this equals() override. What I am really trying to say is, I like to understand things deeply, in this case not only, it works basically in this and that way why but why it even exists as a part of our world:-)
Yes by default equals method implements == in Object class . But you can Override the equals method in your own class to change the way equality is done between two objects of the same class. For example the equals method in String class is overridden as follows:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
So this is the reason that for the following code:
String s1 = new String("java");
String s2 = new String("java");
s1==s2 returns false since both are referencing different objects on heap. Whereas s1.equals(s2) returns true since now the equals being called is what defined within String class where String objects are compared on the basis of contents of String.
the equals method in the String class is overridden and it tries to check if all the characters in both the Strings are equal or not. If found then it returns true. So the behavior of equals method in String class is different from the normal object class implementation of it.
I'm going to answer your question with reservations, but you should know that you are hurting yourself if the intent of the question was to get you to learn and your solution was to ask StackOverflow. That aside...
This behavior is intentional.
The default equals() method on java.lang.Object compares memory addresses, which means that all objects are different from each other (only two references to the same object will return true).
java.lang.Integer overrides this to compare the value of the Integers, so two different Integers both representing the number two compare equal. If you used == instead, you would get false for both cases.
Standard practice in Java is to override the equals method to return true for objects which have the same logical value, even if they were created at different times (or even with different parameters). It's not very useful to have objects representing numbers if you don't have a way to ask, "do these two things represent the same value?".
Incidentally, and this is a tangent here, Java actually keeps a cache of Integer objects for small values. So sometimes you may get two Integer objects where even the == operator will return true, despite you getting them from two different sources. You can even get code that behaves differently for larger integers than it does for smaller, without having it look at the integral values!
This is intended behaviour.
Object.equals() considers the object identity (i.e. an object is only equal to itself), which is the only thing you can do for generic objects.
Integer overrides the method to depend on the integer value, since two Integer objects with the same value are logically equal. Many other classes also override equals() since it's a core mechanism of the standard API and a lot of functionaliy e.g. in the collections framework depends on it.
Why do are you puzzled by the behaviour anyway? Most people are only confused by the == operator not behaving like that (it works like Object.equals()).
The signature of Object.equals() is public boolean equals(Object). If you define a method public boolean equals(MyClass), you're adding a new method, with a different signature, instead of overriding (or redefining, if you prefer) the Object.equals() method.
Since all the collections call the Object.equals() method, your new method would never be called by anybody except your own code, and would thus be almost useless. For example, if you create a Set<MyClass>, it will consider that two instances are different, although your equals(MyClass) method considers them equal.
It is because most classes in Java (lists, queues, maps etc.) use the boolean equals(Object obj) method. At the time when Java was being designed way back in the nineties, Generics did not exist.
Comparison methods using for example the Comparator or Comparable, were updated to support generics, and thus take the right type (avoiding the instanceof) of your class directly. Object.equals() just takes a generic Object.
If you overload .equals() with new signatures, the other collections won't know about your new equals() methods and will still call the old original one provided by Object, so you have to stick with that and use instanceof. Remember overloading does not have the same effect of overriding. In overriding the subclass method gets called, since it has exactly the same signature. In overloading, you are just providing alternative functionality with a different signature, so the caller has to know about it.
Alternatively, instead of using the equals() method, maybe you can change your code a little to use the newer comparison methods with generics. Most collections have been updated to support Comparator, Comparable etc. with Generics too.