Java: Class.isInstance vs Class.isAssignableFrom

Пусть clazz будет некоторым Class и obj быть некоторым Object.

Есть

clazz.isAssignableFrom(obj.getClass())

всегда совпадает с

clazz.isInstance(obj)

?

Если нет, каковы различия?

Ответ 1

clazz.isAssignableFrom(Foo.class) будет истинным всякий раз, когда класс, представленный объектом clazz, является суперклассом или суперинтерфейсом Foo.

clazz.isInstance(obj) будет истинным всякий раз, когда объект obj является экземпляром класса clazz.

То есть:

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

всегда истинно.

Ответ 2

Оба ответа находятся в шаге, но ни один из них не является полным ответом.

MyClass.class.isInstance(obj) предназначен для проверки экземпляра. Он возвращает true, если параметр obj не равен нулю и может быть отброшен до MyClass без повышения a ClassCastException. Другими словами, obj является экземпляром MyClass или его подклассов.

MyClass.class.isAssignableFrom(Other.class) вернет true, если MyClass совпадает с суперклассом или суперинтерфейсом, Other. Other может быть классом или интерфейсом. Он отвечает true, если Other можно преобразовать в 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
    {
    }
}

И вывод:

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

Ответ 3

Я думаю, что результат для этих двух должен всегда быть одним и тем же. Разница в том, что вам нужен экземпляр класса для использования isInstance, а просто для объекта Class для использования isAssignableFrom.

Ответ 4

Для краткости мы можем понять эти два API, как показано ниже:

  • X.class.isAssignableFrom(Y.class)

Если X и Y являются одним и тем же классом, или X является супер-классом Y или супер-интерфейсом, верните true, иначе false.

  1. X.class.isInstance(у):

Скажите, что y - это экземпляр класса Y, если X и Y являются одним и тем же классом, или X является супер-классом Y или супер-интерфейсом, верните true, в противном случае false.