Позвольте clazz
быть некоторыми Class
и obj
быть некоторыми Object
.
Является
clazz.isAssignableFrom(obj.getClass())
всегда так же, как
clazz.isInstance(obj)
?
Если нет, в чем различия?
NullPointerException
если obj == null
.
Позвольте clazz
быть некоторыми Class
и obj
быть некоторыми Object
.
Является
clazz.isAssignableFrom(obj.getClass())
всегда так же, как
clazz.isInstance(obj)
?
Если нет, в чем различия?
NullPointerException
если obj == null
.
Ответы:
clazz.isAssignableFrom(Foo.class)
будет истинным, когда класс, представленный clazz
объектом, является суперклассом или суперинтерфейсом Foo
.
clazz.isInstance(obj)
будет истинным всякий раз, когда объект obj
является экземпляром класса clazz
.
То есть:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
всегда верно, пока clazz
и не obj
равны нулю.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));
-> Это верно и для интерфейсов.
obj
есть, null
то clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
брошу NullPointerException
и не вернусь true
.
Оба ответа находятся в поле зрения, но ни один не является полным ответом.
MyClass.class.isInstance(obj)
для проверки экземпляра. Он возвращает true, когда параметр obj не равен NULL и может быть приведен к MyClass
без повышения a 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();
}
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)
? Я растерялся из-за выхода :)
isAssignableFrom()
бросает a, NullPointerException
если объект нулевой, тогда как isInstance()
просто возвращает false. Это настоящий ответ.
Я думаю, что результат для этих двух всегда должен быть одинаковым. Разница в том, что вам нужен экземпляр класса для использования, isInstance
а только Class
объект для использования isAssignableFrom
.
Comparable.class.isAssignableFrom(Byte.class) == true
но Byte.class.isInstance(Comparable.class) == false
. Другими словами, isInstance()
не является симметричным для интерфейсов, только для подклассов.
Byte.class.isInstance(Comparable.class)
ложно, потому что Class
объект не является экземпляром Byte
. Правильное сравнение Comparable.class.isAssignableFrom(Byte.class)
IS Comparable.class.isInstance((byte) 1)
, что это правда.
Byte
вы обнаружите, что он расширяется Number
и является классом. (byte) 1
не является эквивалентом Byte
. Первый примитив. Последний класс.
byte
к , Byte
так как тип параметра isInstance
является Object
.
Для краткости мы можем понять эти два API, как показано ниже:
X.class.isAssignableFrom(Y.class)
Если X
и Y
являются одним и тем же классом, или X
является Y
суперклассом или суперинтерфейсом, вернуть true, иначе false.
X.class.isInstance(y)
Say y
является экземпляром класса Y
, если X
и Y
является одним и тем же классом, или X
является Y
суперклассом или суперинтерфейсом, возвращает true, в противном случае - false.