Say I have 3 classes like so:
class A {}
class B extends A {}
class C extends A {}
Would it then be possible to determine whether a particular object was an instance of A
, B
, or C
?
I thought that something like this might work:
if (myObject.getClass().isInstance(B.class)) {
// do something for B
} else (myObject.getClass().isInstance(C.class)) {
// do something for C
} else {
// do something for A
}
but after reading a little I think it would always evaluate as B since it's just testing if a cast would work and there's no substantial differences between them.
Do this:
if (myObject instanceof B) {
// do something for B
} else (myObject instanceof C) {
// do something for C
} else {
// do something for A
}
The simpler and faster code is:
if (myObject instanceof B) {
} else if (myObject instanceof C) {
} else if (myObject instanceof A) {
}
Note that the order is important: you have to have the test for A
last, as that will succeed for instances of B
and C
as well.
However, your original code would nearly work. Class.isInstance
checks whether the value really is an instance of the given class or any superclass. So if myObject
is an instance of C
, then B.class.isInstance(myObject)
will return false. All you've got wrong is that you're calling getClass()
on myObject
unnecessarily, instead of using B.class
etc.
This is the approach you would take if you didn't know which classes you were interested in at compile time - the instanceof
operator only works when you can specify the type statically in code.
Now if you want to find out whether myObject
is an instance of exactly B
(and not a subclass) then just use:
if (myObject.getClass() == B.class)
(This will blow up if myObject
is a null reference, of course.)
You also might want to look at the double dispatch idiom which is an OO way of changing behaviour based on the type of an argument in languages which don't support multi-methods.
There is the instanceof
operator that does what you want, as others have answered.
But beware that if you need something like this, it's a sign that there might be a flaw in the design of your program. The better, more object oriented way to do this is by using polymorphism: put a method in the superclass A, override that method in B and C, and call the method on myObject (which should have type A):
A myObject = ...; // wherever you get this from
// Override someMethod in class B and C to do the things that are
// specific to those classes
myObject.someMethod();
instanceof
is ugly and should be avoided as much as possible, just like casting is ugly, potentially unsafe and should be avoided.
you could do this
if (myObject.getClass() == B.class) {
// do something for B (not subclasses of b!!!)
} else if(myObject.getClass() == C.class) {
// do something for C (not subclasses of c!!!)
} else if(myobject.getClass() == A.class) {
// do something for A (not subclasses of A!!)
} else if(myobjects instanceof A){
//all other subclasses of A
}