Java: Class.isInstance против Class.isAssignableFrom - PullRequest
210 голосов
/ 16 октября 2010

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

Есть

clazz.isAssignableFrom(obj.getClass())

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

clazz.isInstance(obj)

Если нет, в чем различия?

Ответы [ 4 ]

201 голосов
/ 16 октября 2010

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

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

То есть:

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

всегда верно, если clazz и obj не равны нулю.

184 голосов
/ 08 августа 2011

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

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

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

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

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

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

  1. X.class.isInstance(y)

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

5 голосов
/ 16 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...