266

Let clazz be some Class and obj be some Object.

Is

clazz.isAssignableFrom(obj.getClass()) 

always the same as

clazz.isInstance(obj) 

?

If not, what are the differences?

5
  • 32
    if obj == null, the second returns false, the first does not. ;) Commented Oct 19, 2010 at 19:07
  • 24
    @PeterLawrey, the first will throw a NullPointerException if obj == null. Commented Jan 9, 2014 at 22:40
  • Found some answer with samples from hrere : mytechnotes.biz/2012/07/… Commented Oct 19, 2015 at 9:08
  • 5
    To the readers: you are about to enter a deep, dark, black hole from which you will never escape. The differences are endless. Give up now while you still can: stackoverflow.com/q/496928/1599699 Commented Oct 17, 2017 at 12:26
  • @ParameshKorrakuti the domain name is changing to tshikatshikaaa.blogspot.com/2012/07/… Commented Feb 9, 2020 at 18:59

4 Answers 4

256

clazz.isAssignableFrom(Foo.class) will be true whenever the class represented by the clazz object is a superclass or superinterface of Foo.

clazz.isInstance(obj) will be true whenever the object obj is an instance of the class clazz.

That is:

clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj) 

is always true so long as clazz and obj are nonnull.

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

6 Comments

this misses the case where the Foo is the same as clazz - in which case it returns true: Pauls top-voted answer below corrects this
I agree that when clazz is a Foo, then clazz.isAssignableFrom(Foo.class) is true. Where did I say otherwise?
@Gili This isn't what uckelman said. Please re-read his answer.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> it's true also for interfaces.
Technicality: If obj is null then clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj) will throw a NullPointerException and not return true.
|
211

Both answers are in the ballpark but neither is a complete answer.

MyClass.class.isInstance(obj) is for checking an instance. It returns true when the parameter obj is non-null and can be cast to MyClass without raising a ClassCastException. In other words, obj is an instance of MyClass or its subclasses.

MyClass.class.isAssignableFrom(Other.class) will return true if MyClass is the same as, or a superclass or superinterface of, Other. Other can be a class or an interface. It answers true if Other can be converted to a MyClass.

A little code to demonstrate:

public class NewMain { public static void main(String[] args) { NewMain nm = new NewMain(); nm.doit(); } class A { } class B extends A { } public void doit() { A myA = new A(); B myB = new B(); A[] aArr = new A[0]; B[] bArr = new B[0]; System.out.println("b instanceof a: " + (myB instanceof A)); // true System.out.println("b isInstance a: " + A.class.isInstance(myB)); //true System.out.println("a isInstance b: " + B.class.isInstance(myA)); //false System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class)); //true System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class)); //false System.out.println("bArr isInstance A: " + A.class.isInstance(bArr)); //false System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr)); //true System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass())); //true } } 

11 Comments

Why in your example "b isAssignableFrom a:" but code is A.class.isAssignableFrom(B.class)? I confused by output :)
ummm... in all your examples "instanceOf" returns true iff "isAssignableFrom" returns true... I don't see the difference this way.
Be careful the text printed out doesn't match the code and can be confusing ... Example: "System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class));"
@Paul The answer, as is, is not helpful, because the reader is left wondering "what is the difference between an object being an instance of a subclass of a class and the object's type being convertible to the class?" Surely, you can see that you've left the reader with as many questions after reading your answer as he had when arriving at this page. A better answer would actually explain the difference (or lack thereof). If there is no difference, the answer should directly state, "there is no practical difference."
More importantly, the reader is left wondering what the heck to use for their purposes. According to the comments in the question, isAssignableFrom() throws a NullPointerException if the object is null, whereas isInstance() just returns false. That's the real answer.
|
10

I think the result for those two should always be the same. The difference is that you need an instance of the class to use isInstance but just the Class object to use isAssignableFrom.

5 Comments

This isn't 100% true. Comparable.class.isAssignableFrom(Byte.class) == true but Byte.class.isInstance(Comparable.class) == false. In other words, isInstance() is not symmetric for interfaces, only for subclasses.
@Gili: You've got it a bit wrong there. Byte.class.isInstance(Comparable.class) is false because a Class object is not an instance of Byte. The correct comparison to Comparable.class.isAssignableFrom(Byte.class) is Comparable.class.isInstance((byte) 1), which is true.
I disagree. If you look up the Javadoc of Byte you will discover it extends Number and is a class. (byte) 1 is not equivalent to Byte. The former is a primitive. The latter is a Class.
@Gili: Autoboxing casts primitive byte to Byte because the parameter type of isInstance is Object.
Okay. My original point was that the calls are not exactly symmetric to each other, but having re-read your answer you never made this assertion so you're right.
8

For brevity, we can understand these two APIs like below:

  1. X.class.isAssignableFrom(Y.class)

If X and Y are the same class, or X is Y's super class or super interface, return true, otherwise, false.

  1. X.class.isInstance(y)

Say y is an instance of class Y, if X and Y are the same class, or X is Y's super class or super interface, return true, otherwise, false.

1 Comment

So you are saying isAssignableFrom takes class and isInstance takes instance. That is the only difference?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.