java:类。isInstance vs Class.isAssignableFrom

clazz为某个Classobj为某个Object

clazz.isAssignableFrom(obj.getClass())

总是一样的

clazz.isInstance(obj)

?

如果不是,有什么不同?

167405 次浏览

我认为这两者的结果应该是一样的。不同的是,你需要一个类的实例来使用isInstance,而只需要Class对象来使用isAssignableFrom

clazz对象表示的类是Foo的超类或超接口时,clazz.isAssignableFrom(Foo.class)将为真。

当对象obj是类clazz的实例时,clazz.isInstance(obj)将为true。

那就是:

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

只要clazzobj为非空,则始终为真。

这两个答案都差不多,但都不是一个完整的答案。

MyClass.class.isInstance(obj)用于检查实例。当参数obj非空且可以强制转换为MyClass而不引发ClassCastException时,它返回true。换句话说,obj是MyClass或其子类的实例。

如果MyClassOther相同,或者是Other的超类或超接口,MyClass.class.isAssignableFrom(Other.class)将返回true。Other可以是类也可以是接口。如果Other可以转换为MyClass,则返回true。

一段演示的小代码:

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
}
}

为简洁起见,我们可以像下面这样理解这两个api:

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

如果XY是同一个类,或者XY的超类或超接口,则返回true,否则返回false。

  1. X.class.isInstance(y)

假设y是类Y的实例,如果XY是同一个类,或者XY的超类或超接口,则返回true,否则返回false。