148

I see gain in performance when using getClass() and == operator over instanceOf operator.

Object str = new Integer("2000"); long starttime = System.nanoTime(); if (str instanceof String) { System.out.println("its string"); } else { if (str instanceof Integer) { System.out.println("its integer"); } } System.out.println((System.nanoTime() - starttime)); starttime = System.nanoTime(); if (str.getClass() == String.class) { System.out.println("its string in equals"); } else { if (str.getClass() == Integer.class) { System.out.println("its integer"); } } System.out.println((System.nanoTime() - starttime)); 

Is there any guideline, which one to use getClass() or instanceOf?

Given a scenario: I know exact classes to be matched, that is String, Integer (these are final classes), etc.

Is using instanceOf operator bad practice ?

4
  • 4
    This is explained in: stackoverflow.com/questions/596462/…. Commented Feb 14, 2011 at 7:43
  • 5
    Your timing method is causing artificial delays and producing incorrect timing results. Swap the order you do the checks and you'll see the first check you do (either == or instanceof) will always be longer. I'd guess it's the println()s. You should never include that stuff in your timing block. Commented Sep 14, 2012 at 18:30
  • 3
    Just one comment apart, to compare performance, use multiple cycle iterations (e.g. 10000) in order to improve accuracy. One single invocation is not a good measure. Commented Mar 18, 2014 at 10:28
  • How large is the difference? Commented Dec 16, 2020 at 14:30

4 Answers 4

177

The reason that the performance1 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 practice2 ?

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().


1 - My answer was written assuming that there are sound performance results that show that getClass() is faster. The benchmark you presented is flawed in a number of respects, and we cannot trust the results it produces; see How do I write a correct micro-benchmark in Java?. Either way, the points I am making are independent of the performance!
2 - 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.

Sign up to request clarification or add additional context in comments.

Comments

49

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.

Comments

19

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()) } 

1 Comment

Don't use isAssignableFrom. The correct way to write o instanceof String using reflection is String.getClass().isInstance(o). The javadoc even says so: This method is the dynamic equivalent of the Java language instanceof operator.
3

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.