AlphaBeta
AlphaBeta

Reputation: 320

Java Object.equals

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

Answers (4)

Ravi K Thapliyal
Ravi K Thapliyal

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

jason
jason

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.equals1, 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

Brian Roach
Brian Roach

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

ajay.patel
ajay.patel

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

Related Questions