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?
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.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> it's true also for interfaces.obj is null then clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj) will throw a NullPointerException and not return true.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 } } A.class.isAssignableFrom(B.class)? I confused by output :)isAssignableFrom() throws a NullPointerException if the object is null, whereas isInstance() just returns false. That's the real answer.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.
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.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.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.byte to Byte because the parameter type of isInstance is Object.For brevity, we can understand these two APIs like below:
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.
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.
NullPointerExceptionifobj == null.