Reputation: 320
Can someone tell me why this returns true ?
I thought if I cast something to e.g. Object
and then call .equals
,
the default implementation from Object
will be used. And s1 == s2 should return false.
Please tell me under which topic I can find more about this behavior.
Set<String> s1 = new HashSet<String>(as("a"));
Set<String> s2 = new HashSet<String>(as("a"));
Object o1 = (Object)s1;
Object o2 = (Object)s2;
System.out.println(o1.equals(o2));
Upvotes: 3
Views: 2868
Reputation: 51711
Because, of Polymorphism.
At runtime, the actual type of object determines which implementation of an instance method should execute. Since, HashSet
inherits an overridden implementation from AbstractSet
it's used for comparison instead of Object.equals()
And, the JavaDocs for AbstractSet#equals() state
Returns true if the given object is also a set, the two sets have the same size, and every member of the given set is contained in this set.
Hence, your equality test prints true.
So, the type of reference (Object, in your case) has little bearing on which version of equals()
is invoked at runtime. It entirely depends on the type of object your reference is pointing to.
Upvotes: 2
Reputation: 241581
Methods in Java are virtual by default. In particular, Object.equals
is virtual (since it's not declared final
). Since HashSet
overrides Object.equals
1, you'll see the HashSet
implementation of equals
used when you invoke the virtual method on an object that has a runtime type of HashSet
(remember dynamic dispatch depends on the runtime type of the receiving object, not the compile-time type).
1: We know that HashSet
overrides Object.equals
because the documentation says that HashSet
derives from AbstractSet
and the documentation for AbstractSet.equals
says:
Compares the specified object with this set for equality. Returns
true
if the specified object is also a set, the two sets have the same size, and every member of the specified set is contained in this set (or equivalently, every member of this set is contained in the specified set). This definition ensures that the equals method works properly across different implementations of the set interface.
which clearly defines value equality whereas the default Object.equals
is identity equality.
Upvotes: 4
Reputation: 76898
Because that's exactly what the Javadocs say it will do:
public boolean equals(Object o)
Compares the specified object with this set for equality. Returns true if the given object is also a set, the two sets have the same size, and every member of the given set is contained in this set. This ensures that the equals method works properly across different implementations of the Set interface.
Just because you cast it to Object
doesn't change what it actually is. The over-ridden equals()
method in HashSet
is used.
Upvotes: 5
Reputation: 1967
Yes the default implementation of equals should return you false. But here default implementation is not called. Object class is extended by everytype in java and that includes HashSet.
Now here if you see, you are referring HashSet object with Object class reference. And hence HashSet equals is called. And hence it returns true.
Upvotes: 1