views:

3792

answers:

5

Which of the following is better?

a instanceof B

or

B.class.isAssignableFrom(a.getClass())

The only difference that I know of is, when 'a' is null, the first returns false, while the second throws an exception. Other than that, do they always give the same result?

+4  A: 

instanceof can only be used with reference types, not primitive types. isAssignableFrom() can be used with any class objects:

a instanceof int  // syntax error
3 instanceof Foo  // syntax error
int.class.isAssignableFrom(int.class)  // true

See http://java.sun.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class).

Adam Rosenfield
+11  A: 

When using "instanceof", you need to know the class of "B" at compile time. When using "isAssignableFrom" it can be dynamic and change during runtime.

Marc Novakowski
A: 

Consider following situation. Suppose you want to check whether type A is a super class of the type of obj, you can go either

... A.class.isAssignableFrom(obj.getClass()) ...

OR

... obj instanceof A ...

But the isAssignableFrom solution requires that the type of obj be visible here. If this is not the case (e.g., the type of obj might be of a private inner class), this option is out. However, the instanceof solution would always work.

algebra
That is not true. Please see "Adam Rosenfield" comment http://stackoverflow.com/questions/496928/what-is-the-difference-between-instanceof-and-class-isassignablefrom/496968#496968
Maxim Veksler
Could you elaborate "That is not true"? The comment you refer to has nothing to do with the scenario in my post. I do have some test code that backs up my explanation.
algebra
A: 

some tests we did in our team show that A.class.isAssignableFrom(B.getClass()) works faster than B instanceof A. this can be very useful if you need to check this on large number of elements.

Milan
A: 

Apart from basic differences mentioned above, there is a core subtle difference between instanceof operator and isAssignableFrom method in Class.

Read ‘instanceof’ as “is this (the left part) the instance of this or any subclass of this (the right part)” and read ‘x.getClass().isAssignableFrom(Y.class)’ as “Can I write X x = new Y()”. In other words, instanceof operator checks if the left object is same or subclass of right class, while isAssiganbleFrom check if we can assign object of the parameter class (from) to the reference of the class on which the method is called.
Note that both of these consider the actual instance not the reference type.

Consider an example of 3 classes A, B and C where C extends B and B extends A.

B b = new C();

System.out.println(b instanceof A); //is b (which is actually class C object) instance of A, yes. This will return true.
System.out.println(b instanceof B); // is b (which is actually class C object) instance of B, yes. This will return true.
System.out.println(b instanceof C); is b (which is actually class C object) instance of C, yes. This will return true. If the first statement would be B b = new B(), this would have been false. System.out.println(b.getClass().isAssignableFrom(A.class));//Can I write C c = new A(), no. So this is false. System.out.println(b.getClass().isAssignableFrom(B.class)); //Can I write C c = new B(), no. So this is false. System.out.println(b.getClass().isAssignableFrom(C.class)); //Can I write C c = new C(), Yes. So this is true.

Ashish Arya
You got it wrong, see this code http://pastebin.com/tfCFs0QY
Maxim Veksler