Дайте clazz
быть Class
и obj
be some Object
.java: Class.isInstance vs Class.isAssignable From
Является
clazz.isAssignableFrom(obj.getClass())
всегда совпадает с
clazz.isInstance(obj)
?
Если нет, то в чем отличия?
Дайте clazz
быть Class
и obj
be some Object
.java: Class.isInstance vs Class.isAssignable From
Является
clazz.isAssignableFrom(obj.getClass())
всегда совпадает с
clazz.isInstance(obj)
?
Если нет, то в чем отличия?
clazz.isAssignableFrom(Foo.class)
будет истинным, если класс, представленный объектом clazz
, является суперклассом или суперинтерфейсом Foo
.
clazz.isInstance(obj)
будет истинным всякий раз, когда объект obj
является экземпляром класса clazz
.
То есть:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
всегда верно.
это пропустит случай, когда Foo такой же, как clazz - в этом случае он возвращает true: Pauls top-voted answer below исправляет это – Rhubarb
Я согласен, что когда clazz является Foo, тогда clazz.isAssignableFrom (Foo.class) истинно , Где я сказал иначе? – uckelman
Это не на 100% верно. 'Comparable.class.isAssignableFrom (Byte.class) == true', но' Byte.class.isInstance (Comparable.class) == false'. Другими словами, 'isInstance()' не является симметричным для интерфейсов, только для подклассов. – Gili
Я думаю, что результат для этих двух должен всегда быть одним и тем же. Разница в том, что вам нужен экземпляр класса для использования isInstance
, но только для объекта Class
для использования isAssignableFrom
.
Это не 100% истинно. 'Comparable.class.isAssignableFrom (Byte.class) == true', но' Byte.class.isInstance (Comparable.class) == false'. Другими словами, 'isInstance()' не является симметричным для интерфейсов, только для подклассов. – Gili
@Gili: У тебя там немного не так. 'Byte.class.isInstance (Comparable.class)' false, потому что объект 'Class' не является экземпляром' Byte'. Правильное сравнение с 'Comparable.class.isAssignableFrom (Byte.class)' является 'Comparable.class.isInstance ((byte) 1)', что верно. – ColinD
Я не согласен. Если вы посмотрите на Javadoc 'Byte', вы обнаружите, что он расширяет« Number »и является классом. '(byte) 1' не эквивалентен' Byte'. Первый - примитив. Последний класс. – Gili
Оба ответа находятся на футбольном поле, но ни один из них не является полным ответом.
MyClass.class.isInstance(obj)
предназначен для проверки экземпляра. Он возвращает true, когда параметр obj не равен нулю и может быть отброшен до 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
В третьей и второй строках строки говорят «bArr isInstance aArr», но код отличается. –
Почему в вашем примере «b isAssignableFrom a:», но код «A.class.isAssignableFrom (B.class)»? Я запутался в выходе :) –
MyClass.class.isInstance (obj) также будет работать для интерфейсов: _ Если этот объект класса представляет собой интерфейс, этот метод возвращает true, если класс или любой суперкласс указанного аргумента объекта реализует этот интерфейс. – Patrick
Для краткости, мы можем понять эти два API, как показано ниже:
Если X и Y являются одним и тем же классом, либо X является супер-классом Y или супер-интерфейсом, верните true, иначе false.
Скажите, что y является экземпляром класса Y, если X и Y являются одним и тем же классом, или X является суперклассическим или супер-интерфейсом Y, верните true, иначе false.
если obj == null, второй возвращает false, первый - нет. ;) –
@PeterLawrey, первый будет вызывать 'NullPointerException', если' obj == null'. – ryvantage
Нашел ответ с образцами из hrere: http://www.mytechnotes.biz/2012/07/java-instanceof-isassignablefrom-or.html –