How to check if a subclass is an instance of a class at runtime?

141,517

Solution 1

You have to read the API carefully for this methods. Sometimes you can get confused very easily.

It is either:

if (B.class.isInstance(view))

API says: Determines if the specified Object (the parameter) is assignment-compatible with the object represented by this Class (The class object you are calling the method at)

or:

if (B.class.isAssignableFrom(view.getClass()))

API says: 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

or (without reflection and the recommended one):

if (view instanceof B)

Solution 2

if(view instanceof B)

This will return true if view is an instance of B or the subclass A (or any subclass of B for that matter).

Solution 3

Maybe I'm missing something, but wouldn't this suffice:

if (view instanceof B) {
    // this view is an instance of B
}

Solution 4

Class.isAssignableFrom() - works for interfaces as well. If you don't want that, you'll have to call getSuperclass() and test until you reach Object.

Solution 5

It's the other way around: B.class.isInstance(view)

Share:
141,517

Related videos on Youtube

iamamused
Author by

iamamused

Updated on July 05, 2022

Comments

  • iamamused
    iamamused almost 2 years

    In an android app test suite I have a class like this where B is a view:

    public class A extends B {
    ... etc...
    }
    

    now I have a list of view objects which may contain A objects but in this case I only care if they're subclasses or "instances of" B. I'd like to do something like:

    ArrayList<View> viewList = getViews();
    Iterator<View> iterator = viewList.iterator();
    while (iterator.hasNext() && viewList != null) {
        View view = iterator.next();
        if (view.getClass().isInstance(B.class)) {
            // this is an instance of B
        }
    }
    

    The problem is that when the if encounters an A object it doesn't evaluate to an "instance of B". Is there a way to do isSubclassOf or something?

    • ishmeister
      ishmeister over 14 years
      From Effective C++, by Scott Meyers : "Anytime you find yourself writing code of the form "if the object is of type T1, then do something, but if it's of type T2, then do something else," slap yourself. Could you not use an overridden method instead? Or perhaps something like the visitor pattern.
    • iamamused
      iamamused over 14 years
      It's for a test case so the code is not actually in the production app, it's to test to make sure things are using the right classes :)
    • Timofey
      Timofey about 12 years
      if viewList array is null, then your program crashes, even check in while does not help.
    • kiwicomb123
      kiwicomb123 over 7 years
      Class invariant assertions is a case where this is done. (As iamamused said)
    • joseluisbz
      joseluisbz about 5 years
  • Ben Clayton
    Ben Clayton over 11 years
    +1 for if (view instanceof B). Simple and works.
  • ArtOfWarfare
    ArtOfWarfare over 11 years
    I'd like to mention that B must be imported in the current .java file for this to work. Eclipse will flag the line as having an error but offer no helpful solutions otherwise (wasted nearly an hour trying different syntax before realizing I just hadn't imported the class file.) For anyone wondering, the correct syntax is ((instance name) instanceof (Class name)). The word class doesn't show up anywhere in it.
  • Qix - MONICA WAS MISTREATED
    Qix - MONICA WAS MISTREATED over 11 years
    Note that instanceof won't work for generics due to erasure.
  • Hardcoded
    Hardcoded about 11 years
    @Qix Thanks for the info. Erasures are a pain in more than one body part, but working without Generics is worse.
  • Qix - MONICA WAS MISTREATED
    Qix - MONICA WAS MISTREATED about 11 years
    To be honest I don't even view Java's generics as true generics; Java's generics are simply syntactic sugar for type safety (or, more importantly, enforcement). They are purely compile time and I think most people coming from C++ and subsequently templates will have a hard time grasping the concept of erasure.
  • Hardcoded
    Hardcoded about 11 years
    The method is badly named and documented. It won't help with the problem, since neither A nor B have any generics.
  • Hardcoded
    Hardcoded over 9 years
    Don't do something like catching Exception and checking for the class of the exception, if you don't have a REALLY good reason for it. do instead: } catch (SQLException e) { } catch (Exception e){ }
  • David
    David over 4 years
    not recommendable to test something using try ... catch