Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Can a.equals(b) be true for a b which does not pass the instanceof test for the class of a?

 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The title asks the whole question. Intuitively it doesn't make much sense for that to happen, but is there any such restriction that I am not aware of? I can't find any in the API. I understand the implications though (if a.equals(b) is true, then a.hashCode() == b.hashCode() must be true, even with B (class of b) being completely unrelated to A (class of A.) This question was prompted by one of the Enthuware quizzes.

Thanks,

Ruben
 
Moojid Hamid
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In addition to hash code equality, if a.equals(b) then b.equals(a) must also be true, and if a.equals(b) and b.equals(c) then a.equals(c) must also be true.
 
sudipto shekhar
Ranch Hand
Posts: 823
Chrome Eclipse IDE Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
equals() and instanceof operator are they inter-related? I mean two Dog objects may not be equal but may be an instanceof Animal..
Please correct me if I am thinking in the wrong direction
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are both right, but my question was quite different. My question is: Is it legal to code an equals(Object) method for a class A such that it will return true in some cases for objects of class B, where b instanceof A is false? I don't see any restrictions in the API saying that you can't do that, but doing so would be quite impractical, since if a.equals(b) == true, then a.hashCode() == b.hashCode(), but then you are requiring the hashCode() implementations of two different classes to abide by some sort of contract as well. I guess the answer to my question might be "there are no rules against that, but you should never do it."
 
Leandro Coutinho
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think that there is a restriction. If you override it, you can do whatever you want (class D equals F that equals z, ...), but it only needs to return a boolean (offcourse =D).

I don't know why you are asking this. I don't see any reason to two objects of different classes be equals.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm asking this because I saw this question in one of the mocks (like I said earlier.)
 
Bob Ruth
Ranch Hand
Posts: 320
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just took the following at face value:

K & B 5.0, pg 527

First, be sure that the object being tested is of the correct type! It comes in polymorphically as type Object, so you need to do an instanceof test on it. Having two objects of different class types be considered equal is usually not a good idea, but that's a design issue we won't go into here. Besides, you'd have to do the instanceof test just to be sure that you could cast the object argument to the correct type so that you can access it's methods or variables in order to actually do the comparison. Remember, if the object doesn't pass the instanceof test, then you'll get a runtime ClassCastException.

Of course, I know that you can code around just about anything... but this demonstrates to me that there is a reason for adhering to that policy.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bob Ruth wrote:I just took the following at face value:

K & B 5.0, pg 527

First, be sure that the object being tested is of the correct type! It comes in polymorphically as type Object, so you need to do an instanceof test on it. Having two objects of different class types be considered equal is usually not a good idea, but that's a design issue we won't go into here. Besides, you'd have to do the instanceof test just to be sure that you could cast the object argument to the correct type so that you can access it's methods or variables in order to actually do the comparison. Remember, if the object doesn't pass the instanceof test, then you'll get a runtime ClassCastException.

Of course, I know that you can code around just about anything... but this demonstrates to me that there is a reason for adhering to that policy.

I was aware of that also, Bob. I was wondering why there is no official contract specification in the API regarding this, as it indeed seems it would be a really bad idea to consider two objects of unrelated classes be equal to each other.
 
Moojid Hamid
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Having two objects of different class types be considered equal is usually not a good idea, but that's a design issue


I think this pretty much answers the question. Yes it is a bad idea to do it but there are some scenarios where it could be done, e.g. implementing a balanced binary red/black tree, again not the best approach but certainly possible.

The reason I quoted the contract earlier is that if we code the equals method in a.class to allow for equality to b.class we will have to do the same to b.class equal method. This means that the designer intentionally designed the two classes in that manner. As far as API is concerned, if it walks like a duck and talks like a duckā€¦

 
Henry Wong
author
Marshal
Pie
Posts: 20904
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try this...



And of course, an ArrayList is NOT an instanceof LinkedList.

Henry
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:Try this...



And of course, an ArrayList is NOT an instanceof LinkedList.

Henry

Excellent example, thanks! I hadn't thought of it, but it makes the point very clearly. The List interface specifies expected behavior for equals(), which in this case is that any two instances of implementing classes of List of the same length, and whose corresponding elements are equal, are considered equal.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic