java:Class.isInstance vs Class.isAssignableFrom

Alb*_*ert 221 java

clazz一些Classobj一些Object.

clazz.isAssignableFrom(obj.getClass())
Run Code Online (Sandbox Code Playgroud)

总是一样的

clazz.isInstance(obj)
Run Code Online (Sandbox Code Playgroud)

如果没有,有什么区别?

uck*_*man 209

clazz.isAssignableFrom(Foo.class)只要clazz对象表示的类是超类或超级接口,它就是真的Foo.

clazz.isInstance(obj)只要对象obj是类的实例,它就会为true clazz.

那是:

clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
Run Code Online (Sandbox Code Playgroud)

只要clazz并且obj是非空的,它总是正确的.

  • @Gili这不是uckelman所说的.请重新阅读他的答案. (5认同)
  • 这错过了Foo与clazz相同的情况 - 在这种情况下它返回true:下面的Pauls顶级投票回答纠正了这个问题 (3认同)
  • 我同意当clazz是Foo时,clazz.isAssignableFrom(Foo.class)是真的.我在哪里说的不是吗? (3认同)
  • `字节b = 3; Comparable.class.isAssignableFrom(b.getClass())== Comparable.class.isInstance(b));` - >对于接口也是如此. (2认同)

Pau*_*aul 189

这两个答案都在球场上,但两者都不是一个完整的答案.

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

MyClass.class.isAssignableFrom(Other.class)如果MyClass与,或者是超类或超级接口相同,则返回true Other. Other可以是类或接口.如果Other可以转换为a ,则回答为true MyClass.

一个小代码来演示:

public class NewMain
{
    public static void main(String[] args)
    {
        NewMain nm = new NewMain();
        nm.doit();
    }

    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));
        System.out.println("b isInstance a: " + A.class.isInstance(myB));
        System.out.println("a isInstance b: " + B.class.isInstance(myA));
        System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class));
        System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class));
        System.out.println("bArr isInstance A: " + A.class.isInstance(bArr));
        System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr));
        System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass()));
    }

    class A
    {
    }

    class B extends A
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

并输出:

b instanceof a: true
b isInstance a: true
a isInstance b: false
b isAssignableFrom a: true
a isAssignableFrom b: false
bArr isInstance A: false
bArr isInstance aArr: true
bArr isAssignableFrom aArr: true
Run Code Online (Sandbox Code Playgroud)

  • @Paul答案是没有用的,因为读者会想知道"作为类的子类实例的对象与可转换为类的对象类型之间有什么区别?" 当然,你可以看到你在阅读完答案时已经给读者留下了许多问题,就像他到达这个页面时一样.更好的答案实际上可以解释差异(或缺乏差异).如果没有差异,答案应直接说明"没有实际差异". (20认同)
  • 为什么在你的例子中"b isAssignableFrom a:"但是代码是`A.class.isAssignableFrom(B.class)`?我对输出感到困惑:) (10认同)
  • 嗯......在你的所有例子中,"instanceOf"返回true iff"isAssignableFrom"返回true ...我没有看到这种方式的区别. (4认同)
  • 请注意打印出来的文本与代码不匹配并且可能会造成混淆......例如:“System.out.println("b isAssignableFrom a:" + A.class.isAssignableFrom(B.class));” (2认同)
  • 更重要的是,读者不禁要问到底要用什么来达到目的。根据问题中的注释,如果对象为null,则isAssignableFrom()会抛出NullPointerException,而isInstance()只会返回false。那才是真正的答案。 (2认同)

Col*_*inD 7

我认为这两个的结果应该总是相同的。区别在于您需要使用该类的实例,isInstance而仅Class需要使用该对象isAssignableFrom

  • @吉利:你在这里有点不对劲。Byte.class.isInstance(Comparable.class)是错误的,因为Class对象不是Byte的实例。与Comparable.class.isAssignableFrom(Byte.class)的正确比较是Comparable.class.isInstance((byte)1),这是正确的。 (6认同)
  • @Gili:自动装箱将原始的`byte`强制转换为`Byte`,因为isInstance的参数类型是Object。 (2认同)
  • 好的。我的原始观点是,调用之间并不是完全对称的,但是重新读取您的答案后,您再也没有提出这个主张,所以您是对的。 (2认同)

小智 6

为简洁起见,我们可以理解以下两个API:

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

如果XY是同一类的,或者XY"超级类或超接口,返回true,否则为false.

  1. X.class.isInstance(y)

Say y是类的实例Y,if XY是同一个类,或者XY超类或超级接口,返回true,否则返回false.