instanceof tests whether the object reference on the left-hand side (LHS) is an instance of the type on the right-hand side (RHS) or some subtype. getClass() == ... tests whether the types are identical.
The instanceof operator and isInstance() method both are used for checking the class of the object. But the main difference comes when we want to check the class of objects dynamically then isInstance() method will work. There is no way we can do this by instanceof operator.
The Java Object getClass() method returns the class name of the object. The syntax of the getClass() method is: object.getClass()
instanceof is a binary operator we use to test if an object is of a given type. The result of the operation is either true or false. It's also known as a type comparison operator because it compares the instance with the type. Before casting an unknown object, the instanceof check should always be used.
The reason that the performance of instanceof
and getClass() == ...
is different is that they are doing different things.
instanceof
tests whether the object reference on the left-hand side (LHS) is an instance of the type on the right-hand side (RHS) or some subtype.
getClass() == ...
tests whether the types are identical.
So the recommendation is to ignore the performance issue and use the alternative that gives you the answer that you need.
Is using the
instanceOf
operator bad practice ?
Not necessarily. Overuse of either instanceOf
or getClass()
may be "design smell". If you are not careful, you end up with a design where the addition of new subclasses results in a significant amount of code reworking. In most situations, the preferred approach is to use polymorphism.
However, there are cases where these are NOT "design smell". For example, in equals(Object)
you need to test the actual type of the argument, and return false
if it doesn't match. This is best done using getClass()
.
Terms like "best practice", "bad practice", "design smell", "antipattern" and so on should be used sparingly and treated with suspicion. They encourage black-or-white thinking. It is better to make your judgements in context, rather than based purely on dogma; e.g. something that someone said is "best practice". I recommend that everyone read No Best Practices if they haven't already done so.
Do you want to match a class exactly, e.g. only matching FileInputStream
instead of any subclass of FileInputStream
? If so, use getClass()
and ==
. I would typically do this in an equals
, so that an instance of X isn't deemed equal to an instance of a subclass of X - otherwise you can get into tricky symmetry problems. On the other hand, that's more usually useful for comparing that two objects are of the same class than of one specific class.
Otherwise, use instanceof
. Note that with getClass()
you will need to ensure you have a non-null reference to start with, or you'll get a NullPointerException
, whereas instanceof
will just return false
if the first operand is null.
Personally I'd say instanceof
is more idiomatic - but using either of them extensively is a design smell in most cases.
I know it has been a while since this was asked, but I learned an alternative yesterday
We all know you can do:
if(o instanceof String) { // etc
but what if you dont know exactly what type of class it needs to be? you cannot generically do:
if(o instanceof <Class variable>.getClass()) {
as it gives a compile error.
Instead, here is an alternative - isAssignableFrom()
For example:
public static boolean isASubClass(Class classTypeWeWant, Object objectWeHave) {
return classTypeWeWant.isAssignableFrom(objectWeHave.getClass())
}
getClass() has the restriction that objects are only equal to other objects of the same class, the same run time type, as illustrated in the output of below code:
class ParentClass{
}
public class SubClass extends ParentClass{
public static void main(String []args){
ParentClass parentClassInstance = new ParentClass();
SubClass subClassInstance = new SubClass();
if(subClassInstance instanceof ParentClass){
System.out.println("SubClass extends ParentClass. subClassInstance is instanceof ParentClass");
}
if(subClassInstance.getClass() != parentClassInstance.getClass()){
System.out.println("Different getClass() return results with subClassInstance and parentClassInstance ");
}
}
}
Outputs:
SubClass extends ParentClass. subClassInstance is instanceof ParentClass.
Different getClass() return results with subClassInstance and parentClassInstance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With