Any reason to prefer getClass() over instanceof when generating .equals()? - java

I'm using Eclipse to generate .equals() and .hashCode(), and there is an option labeled "Use 'instanceof' to compare types". The default is for this option to be unchecked and use .getClass() to compare types. Is there any reason I should prefer .getClass() over instanceof?
Without using instanceof:
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Using instanceof:
if (obj == null)
return false;
if (!(obj instanceof MyClass))
return false;
I usually check the instanceof option, and then go in and remove the "if (obj == null)" check. (It is redundant since null objects will always fail instanceof.) Is there any reason that's a bad idea?

Josh Bloch favors your approach:
The reason that I favor the instanceof approach is that when you use the getClass approach, you have the restriction that objects are only equal to other objects of the same class, the same run time type. If you extend a class and add a couple of innocuous methods to it, then check to see whether some object of the subclass is equal to an object of the super class, even if the objects are equal in all important aspects, you will get the surprising answer that they aren't equal. In fact, this violates a strict interpretation of the Liskov substitution principle, and can lead to very surprising behavior. In Java, it's particularly important because most of the collections (HashTable, etc.) are based on the equals method. If you put a member of the super class in a hash table as the key and then look it up using a subclass instance, you won't find it, because they are not equal.
See also this SO answer.
Effective Java chapter 3 also covers this.

If you use instanceof, making your equals implementation final will preserve the symmetry contract of the method: x.equals(y) == y.equals(x). If final seems restrictive, carefully examine your notion of object equivalence to make sure that your overriding implementations fully maintain the contract established by the Object class.
What I'm trying to get at here is that if you believe getClass() is the only reliable way to preserve symmetry, you are probably using equals() the wrong way.
Sure, it's easy to use getClass() to preserve the symmetry required of equals(), but only because x.equals(y) and y.equals(x) are always false. Liskov substitutability would encourage you to find a symmetry-preserving implementation that can yield true when it makes sense. If a subclass has a radically different notion of equality, is it really a subclass?

The reason to use getClass is to ensure the symmetric property of the equals contract. From equals' JavaDocs:
It is symmetric: for any non-null
reference values x and y, x.equals(y)
should return true if and only if
y.equals(x) returns true.
By using instanceof, it's possible to not be symmetric. Consider the example:
Dog extends Animal.
Animal's equals does an instanceof check of Animal.
Dog's equals does an instanceof check of Dog.
Give Animal a and Dog d (with other fields the same):
a.equals(d) --> true
d.equals(a) --> false
This violates the symmetric property.
To strictly follow equal's contract, symmetry must be ensured, and thus the class needs to be the same.

Angelika Langers Secrets of equals gets into that with a long and detailed discussion for a few common and well-known examples, including by Josh Bloch and Barbara Liskov, discovering a couple of problems in most of them. She also gets into the instanceof vs getClass. Some quote from it
Conclusions
Having dissected the four arbitrarily chosen examples of implementations of equals() , what do we conclude?
First of all: there are two substantially different ways of performing the check for type match in an implementation of equals() . A class can allow mixed-type comparison between super- and subclass objects by means of the instanceof operator, or a class can treat objects of different type as non-equal by means of the getClass() test. The examples above illustrated nicely that implementations of equals() using getClass() are generally more robust than those implementations using instanceof .
The instanceof test is correct only for final classes or if at least method equals() is final in a superclass. The latter essentially implies that no subclass must extend the superclass's state, but can only add functionality or fields that are irrelevant for the object's state and behavior, such as transient or static fields.
Implementations using the getClass() test on the other hand always comply to the equals() contract; they are correct and robust. They are, however, semantically very different from implementations that use the instanceof test. Implementations using getClass() do not allow comparison of sub- with superclass objects, not even when the subclass does not add any fields and would not even want to override equals() . Such a "trivial" class extension would for instance be the addition of a debug-print method in a subclass defined for exactly this "trivial" purpose. If the superclass prohibits mixed-type comparison via the getClass() check, then the trivial extension would not be comparable to its superclass. Whether or not this is a problem fully depends on the semantics of the class and the purpose of the extension.

This is something of a religious debate. Both approaches have their problems.
Use instanceof and you can never add significant members to subclasses.
Use getClass and you violate the Liskov substitution principle.
Bloch has another relevant piece of advice in Effective Java Second Edition:
Item 17: Design and document for inheritance or prohibit it

Correct me if I am wrong, but getClass() will be useful when you want to make sure your instance is NOT a subclass of the class you are comparing with. If you use instanceof in that situation you can NOT know that because:
class A { }
class B extends A { }
Object oA = new A();
Object oB = new B();
oA instanceof A => true
oA instanceof B => false
oB instanceof A => true // <================ HERE
oB instanceof B => true
oA.getClass().equals(A.class) => true
oA.getClass().equals(B.class) => false
oB.getClass().equals(A.class) => false // <===============HERE
oB.getClass().equals(B.class) => true

If you want to ensure only that class will match then use getClass() ==. If you want to match subclasses then instanceof is needed.
Also, instanceof will not match against a null but is safe to compare against a null. So you don't have to null check it.
if ( ! (obj instanceof MyClass) ) { return false; }

It depends if you consider if a subclass of a given class is equals to its parent.
class LastName
{
(...)
}
class FamilyName
extends LastName
{
(..)
}
here I would use 'instanceof', because I want a LastName to be compared to FamilyName
class Organism
{
}
class Gorilla extends Organism
{
}
here I would use 'getClass', because the class already says that the two instances are not equivalent.

instanceof works for instences of the same class or its subclasses
You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.
ArryaList and RoleList are both instanceof List
While
getClass() == o.getClass() will be true only if both objects ( this and o ) belongs to exactly the same class.
So depending on what you need to compare you could use one or the other.
If your logic is: "One objects is equals to other only if they are both the same class" you should go for the "equals", which I think is most of the cases.

Both methods have their problems.
If the subclass changes the identity, then you need to compare their actual classes. Otherwise, you violate the symmetric property. For instance, different types of Persons should not be considered equivalent, even if they have the same name.
However, some subclasses don't change identity and these need to use instanceof. For instance, if we have a bunch of immutable Shape objects, then a Rectangle with length and width of 1 should be equal to the unit Square.
In practice, I think the former case is more likely to be true. Usually, subclassing is a fundamental part of your identity and being exactly like your parent except you can do one little thing does not make you equal.

Actually instanceof check where an object belongs to some hierarchy or not. ex: Car object belongs to Vehical class. So "new Car() instance of Vehical" returns true. And "new Car().getClass().equals(Vehical.class)" return false, though Car object belongs to Vehical class but it's categorized as a separate type.

Related

Java reflection check if passed Objects are same type

I have a class with compare method. The method takes two objects as arguments.
With java reflection I was able to get all the private and protected field and with some fancy stuff check their return types and do what I want to do with them.
This is good for me personaly. I know what I want to do so I just compare two objects of same type and thats all.
BUT ... this is used by many people ...and they sometimes are unable to read a Javadocs and comments and other stuff I put there so I have to check if they are passing object of same type. For example you have :
Car a, Car b , Truck a, Truck b ... and so on..
I need to check if the two passed arguments are actually the same type for comparing (Car with car , Truck with truck..)
So ... I dont know the stuff.. Should I use the reflection for listing the size of all fields and then check if all the fields have the same name ?
Or is there a better solution ? Becouse writing something like if the fieldsOfA.size is same as fieldOfB.size ... and then for loop for this if they are same to check the names looks kinda weird..
Also another problem.
Those objects have lists of some other object - for example Car has a list of Wheels..
And you are comparing the wheels with other car.
They have like Wheel 1 , Wheel 2 , Wheel 3, Wheel 4 in list..
and the second car has Wheel1, Wheel 2, WHeel 4 and WHeel 3 ..
So the objects are same , but just have switched positions..is there a way to prevent this ? I have a tracking code that stores every difference in those objects.. So if they have different positions it gives me two changes.. Wheel 3 is different from other car and wheel 4 is different on other car..
But they are still the same ...
I don't know how to solve this with reflection ... Any Ideas ?
To compare classes just use if(object1.getClass() == object2.getClass())
To be fair, it's either a.getClass().isInstance(b) or a.getClass().isAssignableFrom(b) but I always forget which one is which.
boolean isInstance(Object obj)
Determines if the specified Object is assignment-compatible with the object represented by this Class.
And
boolean isAssignableFrom(Class<?> cls)
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.
You probably need the first.
You can use the instanceof operator.
For example:
public boolean isCar(Vehicle x) {
if (x instanceOf Car) {
return true;
} else {
return false;
}
// note: you can also just do "return x instanceof Car"
}
This sounds like you're attempting to write a General Purpose Equals Method. Just in case you are: be aware that this will fail in the general case, because object equality does not necessarily mean all fields are equal, or even that all public fields are equal. It is possible for two Java objects to be intentionally equal even if some fields are different. Equality between two instances of a given class is defined by the programmer designing that class, and anyone subclassing it implicitly abides by their equality contract.
Given that, it's generally a bad idea to attempt to dig out an object's superclass' private fields. A much better idea: super.equals().
So, suppose you write a class Truck that extends Vehicle, and Truck defines two private fields, maxLoad and hasTrailerHitch. You define whether two Trucks are equal; suppose you need both these fields to be equal. In reality, you probably also want them to satisfy whatever equality conditions Vehicle defines. So your equals is likely to look something like this:
#Override
public boolean equals(Object obj) {
// check for type
if (!(obj instanceof Truck)) return false;
// check private fields
Truck other = (Truck)obj;
if (this.maxLoad != other.maxLoad ||
this.hasTrailerHitch != other.hasTrailerHitch) return false;
// check for Vehicle equality
if (!super.equals(obj)) return false;
// everything checks out!
return true;
}
I wrote this a bit less compactly than I would in practice, for display purposes. The order of the checks ideally doesn't matter; I put the superclass check last, since I know two private field comparisons runs really fast, but I don't necessarily know what's involved in checking Vehicles.
Notice how the instanceof works. If someone (including you!) writes a subclass of Truck later, the instanceof will be true, and so if they do the same thing you do and call super.equals(obj), your Truck.equals will check those two private fields, as it should. If, instead of an instanceof check, you had been more strict, say:
if (obj.getClass().getName().equals("my.pkg.Truck")) // ...
then subclasses of Truck would not get these private fields checked properly. Two instances of, say, DumpTruck would never be equals - probably not what you intend.

Check if an object is of the same class as this?

I have a base class for multiple data object types in Java. I want to create an equals method in the base class, that works directly when inherited.
Equality is determined by the two objects
belonging to subclasses of the base class. This is easily achievable using
if (!(anObject instanceof BaseClass))
return false;
having the same ID. The ID field is defined by the base class so we can here test that.
if (this.id != ((BaseClass) anObject).id)
return false;
belonging to the same class. This is where I have the problem. Two objects may be of different types (and so be in different lists), but have the same ID. I have to be able to distinguish them. How can I do this?
Use
this.getClass() == anotherObject.getClass()
instead of instanceof. This will return true only if the two object belong to the same class (it's safe to check if class objects are equal by reference). And after that you may compare the id.
You should read this article for problems when implementing equals.
To make it short: use this.getClass()==other.getClass() instead of instanceof, because otherwise the equals() relationship will not be transitive (superInstance.equals(subInstance) will be true, but subInstance.equals(superInstance) will be false).
If I understand you question correctly, you need a way to differentiate two objects of same Class with same id. If so, for this you may use toString() which gives unique representation of objects unless they are string objects. Of course, you must not have overridden toString() in your base class.
example:You can use this, only for the third case that you mentioned.
if (this.toString()!= anObject.toString())
return false;
You can do that with Class.isInstance() method. In your base class, do this.
public static boolean isAnInstance(Object obj)
{
return BaseClass.class.isInstance(obj);
}
Then you can check
if (BaseClass.isAnInstance(object))
{
// Class of object is 'BaseClass' or
// it extends the 'BaseClass'
}
Hope this helps.
The best practice to know objects equality is to override hashcode() and equals() if you maitain objects in a collection
you can refer Why do we have to override the equals() method in Java?

Should 2 Java objects of different classes ever be equal?

I'm trying to write some generic code to define class equality and hashcodes based on a list of fields. When writing my equals method, I was wondering if, based on Java convention, it should ever be possible for two object of different to be equal. Let me give some examples;
class A {
int foo;
}
class B {
int foo;
}
class C extends A {
int bar;
}
class D extends A {
void doStuff() { }
}
...
A a = new A(); a.foo = 1;
B b = new B(); b.foo = 1;
C c = new C(); c.foo = 1; c.bar = 2;
D d = new D(); d.foo = 1;
a.equals(b); //Should return false, obviously
a.equals(c);
c.equals(a); //These two must be the same result, so I'd assume it must be false, since c cant possible equal a
a.equals(d); //Now this one is where I'm stuck.
I see no reason that in the last example the two shouldn't be equal, but they do have different classes. Anyone know what convention dictates? And if they would be equal, how should an equals method handle that?
Edit: if anyone's interested in the code behind this question, see: https://gist.github.com/thomaswp/5816085 It's a little dirty but I'd welcome comments on the gist.
They could be, but it's typically very difficult to maintain the symmetric and transitive properties of equality in that case. At least while having a useful/intuitive definition of equality.
If you allow a subclass to consider itself equal to an instance of the superclass, then the superclass needs to consider itself equal to an instance of the subclass. Which means that you'll be encoding specific knowledge about the subclass (all possible subclasses?) in the superclass, and downcasting as needed, which isn't very clean.
Or, you do the comparison purely with fields contained in A, and don't override equals() at all. This fixes the above, but has the problem that two instances of C with different values of bar would be considered equal, which is probably not what you want.
Or, you override in C, and compare bar if the other object is an instance of C, but otherwise don't for an instance of A, you have another problem. c1.equals(c2) would be false, but c1.equals(a) would be true, as would c2.equals(a) and so a.equals(c2). This breaks transitivity (since c1 == a and a == c2 implies c1 == c2).
In summary, it's theoretically possible but you would have to cripple your equals implementation to do so. And besides, the runtime class is a property of an object just as much as bar is, so I'd expect objects with different concrete classes to be not equal to each other anyway.
First note: when you override .equals(), you absolutely MUST override .hashCode() as well, and obey the defined contract. This is no joke. If you do not obey THAT, you are doomed to encounter problems.
As to handling equality between different classes inheriting one another, if all these classes have a common member, this can be done as such:
#Override
public int hashCode()
{
return commonMember.hashCode();
}
#Override
public boolean equals(final Object o)
{
if (o == null)
return false;
if (this == o)
return true;
if (!(o instanceof BaseClass))
return false;
final BaseClass other = (BaseClass) o;
return commonMember.equals(other.commonMember); // etc -- to be completed
}
Also remember that you need to follow these rules in order to correctly implement the equals method.
Reflexive : Object must be equal to itself.
Symmetric : if a.equals(b) is true then b.equals(a) must be true.
Transitive : if a.equals(b) is true and b.equals(c) is true then c.equals(a) must be true.
Consistent : multiple invocation of equals() method must result same value until any of properties are modified. So if two objects are equals in Java they will remain equals until any of there property is modified.
Null comparison : comparing any object to null must be false and should not result in NullPointerException. For example a.equals(null) must be false, passing unknown object, which could be null, to equals in Java is is actually a Java coding best practice to avoid NullPointerException in Java.
As Andrzej Doyle rightly said, it becomes difficult to implement the Symetric and Transitive property when it's spread across multiple classes.
Object.equals() is required to be reflexive, symmetric, transitive, consistent across multiple invocations, and x.equals(null) must be false. There are no further requirements beyond that.
If equals() for a class you define does all of those things, then it's an acceptable equals() method. There is no answer to the question of how fine-grained it should be other than the one you provide yourself. You need to ask yourself: Which objects to I want to be equal?
Note, however, that you should have a good reason for making a.equals(b) true when a and b are instances of different classes, as that can make it tricky to implement a correct equals() in both classes.
This question seems to me to indicate a muddy architecture. In theory, if you want to implement .equals such that you compare only specific members of the two instances you can do this, but whether this is a good idea really depends on just what purpose these classes are intended to serve (and even then I think there are better approaches).
Are these objects, more or less, just intended to be nothing more than bags of data? If so, perhaps you should create a separate comparison class that determines whether the two objects are "equivalent enough" for the purposes you need, rather than force the objects themselves to care about some alien, unrelated class. I'd be concerned if my code were concerning itself with potentially unrelated objects just because I thought it might be a good idea for them to know about each other due to temporary convenience. Also, as Andrzej mentioned, it's very problematic for a parent class to know or care about specific implementation details of derived classes. I've seen first-hand how this causes problems both subtle and egregious.
Are the objects "doers" rather than data storage? Since your subclass D implements a method then this indicates that it's more than just a bag of data... and in this case, philosophically, I can't see how it would be a good idea to consider A and D equal based merely on a set of value fields. Compare the fields, yes. Consider them equal or equivalent? No. This sounds like a maintainability nightmare in the long haul.
Here's an example of what I think would be a better idea:
class A implements IFoo{
private int foo;
public int getFoo(){ return foo; }
}
class B implements IFoo{
private int foo;
public int getFoo(){ return foo; }
}
class CompareFoos{
public static boolean isEquivalent(IFoo a, IFoo b){
// compare here as needed and return result.
}
}
IFoo a = new A();
IFoo b = new B();
boolean result = CompareFoos.isEquivalent(a, b);
To some extent it depends on what you want the code to do. As long as you are clear what the equals method will compare then I don't see a problem necessarily. I think the problem really comes when you start making lots of sub-classes (e.g. Class E). There's a danger than that one of the sub-classes won't follow the contract so you could end up with
a.equals(e) --> true
e.equals(a) --> false
which would result in strange behaviour.
Personally I try to avoid equals comparing two different classes and returning true but I have done it a couple of times where the whole class hierarchy was under my control and final.
Consider this example -
abstract class Quadrilateral{
Quadrilateral(int l, int w){
length=l;
width=w;
}
private int length, width;
}
class Rectangle extends Quadrilateral{
Rectangle(int l, int w){super(l,w);}
}
class Square extends Quadrilateral{
Square(int l){super(l, l);}
}
Square s = new Square(3);
Rectangle r = new Rectangle(3,3);
r.equals(s);//This should be true because the rectangle and square are logically the same.
So yes, there are cases where two different classes can be equal. Though clearly this is not common.
No.
Set<Parent> p = new HashSet<>();
p.insert(new Parent(1));
p.insert(new Child(1));
Supposing those two instances are equals, does p contain a Child? Very unclear. More fun:
class Parent {
public int foo = 0;
void foo() {
foo = 1;
}
}
class Child extends Parent {
#Override
void foo() {
foo = 2;
}
}
Set<Parent> set = new HashSet<>();
for(Parent parent : set) {
parent.foo();
System.out.println(parent.foo); // 1 or 2?
}
I challenge you to know what p's element contains without spending more than 1 minute on the Javadoc pages for Set, HashSet, or equals.
The short answer is that in very limited cases (e.g. Integer and Long) it is OK for two objects of different classes to be equal, but it is so hard to pull off correctly that it is generally discouraged. It's hard enough to ensure that you create an equals() method that is Symmetric, Reflexive, and Transitive, but on top of that you should also:
create a hashCode() method that is consistent with equals()
create a compareTo() method that is consistent with equals()
further ensure that the compareTo() method is well behaved
Failure to do that can cause problems with using the objects in Sets, Trees, Hashes, and Sorted Lists.
There's a good article on the the topic of equals() based on part of Josh Bloch's book Effective Java but even that only covers equals(). The book goes into much greater detail, especially about how the problem becomes serious quickly once you start using the objects in collections.
It depends what you need, as #andrzeg said.
One additional thing. Do you want a.equals(d) to be true, but d.equals(a) to be false? when coding you will probably be using instanceof which may or may not be what you want.
I think that this question can be reduced to whether to use instanceof or getClass() in equals() implementation.
If D derives A and your inheritance hierarchy is right then indeed D IS A. It is logical to treat D as any other A and therefore you should be able to check D for equality as you would any other A.
Here is a link where Josh Bloch explains why he favors the instanceof approach.
http://www.artima.com/intv/bloch17.html

How to get the object class in Java?

What is the best way to get the class of an instance ?
What is the recommended way ? and what are the differences (performances) between :
Compare the class
if( this.getClass().equals(MyClass.class) ){
which seems to be the same as this.getClass() == MyClass.class (or perhaps using Class.forName("com.test.MyClass"))
Test the instance of (seems to be the more readable)
if( this instanceof MyClass ){
Test the instance using class
if( MyClass.class.isInstance(myInst) ){
I would recommend this.getClass().equals( MyClass.class) when you want to match a class exactly because "someString" instanceOf Object will produce true because String class is subtype of Object.
This is checking is a relationship between any instance and the class.
In your case any subclass of MyClass will produce true
instanceof tests whether the thing on the left is an instance of the type on the right or some subtype.
getClass() == ...tests whether the types are identical.
Option one only tells you if the class is exactly what you are testing. This is usually not very useful. For example, it's completely pointless for interfaces. If this is actually what you want to do, you can probably use == unless you're messing around with different ClassLoaders, in which case there may be more than one instance of each Class object.
Option two tells you whether the object is statically assignable to the given class (i.e. can be cast to it).
Option three does the same as two, but using the reflection API. You'll only need this if you're doing dynamic typing. The built-in instanceof is more readable and should be much more efficient.

Findbugs warning: Equals method should not assume anything about the type of its argument

When running FindBugs on my project, I got a few instances of the error described above.
Namely, my overriding versions of equals cast the RHS object into the same type as the object in which the overriding version is defined.
However, I'm not sure whether a better design is possible, since AFAIK Java does not allow variance in method parameters, so it is not possible to define any other type for the equals parameter.
Am I doing something very wrong, or is FindBugs too eager?
A different way to phrase this question is: what is the correct behavior if the object passed to equals is not the same type as an LHS: Is this a false, or should there be an exception?
For example:
public boolean equals(Object rhs)
{
MyType rhsMyType = (MyType)rhs; // Should throw exception
if(this.field1().equals(rhsMyType.field1())... // Or whatever
}
Typically, when implementing equals you can check to see whether the class of the argument is equal (or compatible) to the implementing class before casting it. Something like this:
if (getClass() != obj.getClass())
return false;
MyObj myObj = (MyObj) obj;
Doing it this way will prevent the FindBugs warning.
A side note to address a comment:
Some people argue to use instanceof instead of getClass to check type safety. There is a big debate on that, which I was trying not to get into when I noted that you can check for class equality or compatibility, but I guess I can't escape it. It boils down to this - if you use instanceof you can support equality between instances of a class and instances of its subclass, but you risk breaking the symmetric contract of equals. Generally I would recommend not to use instanceof unless you know you need it and you know what you are doing. For more information see:
http://www.artima.com/weblogs/viewpost.jsp?thread=4744
What issues should be considered when overriding equals and hashCode in Java?
http://www.macchiato.com/columns/Durable5.html
http://commons.apache.org/lang/api-release/org/apache/commons/lang/builder/EqualsBuilder.html (Apache common's implementation helper)
http://www.eclipsezone.com/eclipse/forums/t92613.rhtml (Eclipse's default equals generator)
NetBeans generator also uses getClass()
You're probably doing something like this:
public class Foo {
// some code
public void equals(Object o) {
Foo other = (Foo) o;
// the real equals code
}
}
In this example you are assuming something about the argument of equals(): You are assuming it's of type Foo. This needs not be the case! You can also get a String (in which case you should almost definitely return false).
So your code should look like this:
public void equals(Object o) {
if (!(o instanceof Foo)) {
return false;
}
Foo other = (Foo) o;
// the real equals code
}
(or use the more stringent getClass() != o.getClass() mentioned by Dave L.
You could also look at it this way:
Integer i = new Integer(42);
String s = "fourtytwo";
boolean b = i.equals(s);
Is there any reason that this code should throw a ClassCastException instead of finishing normally and setting b to false?
Throwing a ClassCastException as a response to .equals() wouldn't be sensible. Because even if it is a stupid question ("Of course a String is never equal to a Foo!") it's still a valid one with a perfectly fine answer ("no" == false).
I'd recommend to ignore said findbugs warning. In practice, if equals is called with an object of an unexpected class, it is almost certainly a bug, and you want to fail fast on bugs.
For example, if you have an 'ArrayList files' and call files.contains("MyFile.txt"), it would be nice if you got a ClassCastException. Instead, Java just returns false, and it likely takes a long time until you discover that bug.
I start my equals(Object) implementations like this:
if ((object == null) || !(object instaceof ThisClass)) {
return false;
}
This will also prevent the FindBugs warning but will not automatically return false when a subclass of ThisClass is being handed in. It might also be considered equal, especially if its equals(Object) method hasn’t been overridden.

Categories