это пропускает случай, когда Foo - то же самое, что и clazz - в этом случае он возвращает истину: нижеприведенный ответ Паулса с поправкой исправляет это
Rhubarb
3
Я согласен, что когда clazz является Foo, тогда clazz.isAssignableFrom (Foo.class) имеет значение true. Где я сказал иначе?
Uckelman
5
@Gili Это не то, что сказал Укельман. Пожалуйста, перечитайте его ответ.
Puce
2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> Это верно и для интерфейсов.
Puce
1
Техническость: если objесть, nullто clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)брошу NullPointerExceptionи не вернусь true.
Эндрю Мачерет
196
Оба ответа находятся в поле зрения, но ни один не является полным ответом.
MyClass.class.isInstance(obj)для проверки экземпляра. Он возвращает true, когда параметр obj не равен NULL и может быть приведен к MyClassбез повышения a ClassCastException. Другими словами, obj является экземпляром MyClassили его подклассами.
MyClass.class.isAssignableFrom(Other.class)вернет true, если MyClassэто то же самое, или суперкласс или суперинтерфейс,Other . Otherможет быть классом или интерфейсом. Он отвечает истине, если Otherможет быть преобразован в MyClass.
Почему в вашем примере "b isAssignableFrom a:", а код есть A.class.isAssignableFrom(B.class)? Я растерялся из-за выхода :)
Роман Труба
4
хммм ... во всех ваших примерах "instanceOf" возвращает истину, если "isAssignableFrom" возвращает истину ... Я не вижу разницы в этом пути.
Android-разработчик
2
Будьте осторожны, напечатанный текст не соответствует коду и может сбить с толку ... Пример: "System.out.println (" b isAssignableFrom a: "+ A.class.isAssignableFrom (B.class));"
Polster
21
@Paul Ответ, как есть, бесполезен, потому что читатель задается вопросом: «В чем разница между объектом, являющимся экземпляром подкласса класса, и типом объекта, который может быть преобразован в класс?» Конечно, вы можете видеть, что после прочтения вашего ответа у читателя появилось столько вопросов, сколько он получил при посещении этой страницы. Лучший ответ на самом деле объяснил бы разницу (или ее отсутствие). Если нет никакой разницы, ответ должен прямо заявить: «Нет никакой практической разницы».
Александр Дубинский
2
Что еще более важно, читатель задается вопросом, какого черта использовать для своих целей. Согласно комментариям в вопросе, isAssignableFrom()бросает a, NullPointerExceptionесли объект нулевой, тогда как isInstance()просто возвращает false. Это настоящий ответ.
Андрей
6
Я думаю, что результат для этих двух всегда должен быть одинаковым. Разница в том, что вам нужен экземпляр класса для использования, isInstanceа только Classобъект для использования isAssignableFrom.
Это не на 100% верно. Comparable.class.isAssignableFrom(Byte.class) == trueно Byte.class.isInstance(Comparable.class) == false. Другими словами, isInstance()не является симметричным для интерфейсов, только для подклассов.
Гили
6
@ Гили: у вас там немного не так. Byte.class.isInstance(Comparable.class)ложно, потому что Classобъект не является экземпляром Byte. Правильное сравнение Comparable.class.isAssignableFrom(Byte.class)IS Comparable.class.isInstance((byte) 1), что это правда.
ColinD
1
Я не согласен. Если вы посмотрите Javadoc, Byteвы обнаружите, что он расширяется Numberи является классом. (byte) 1не является эквивалентом Byte. Первый примитив. Последний класс.
Гили
2
@Gili: Autoboxing бросает примитивный byteк , Byteтак как тип параметра isInstanceявляется Object.
ColinD
2
Ладно. Первоначально я хотел сказать, что вызовы не совсем симметричны друг другу, но, перечитав свой ответ, вы никогда не делали этого утверждения, поэтому вы правы.
Гили
6
Для краткости мы можем понять эти два 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.
NullPointerException
еслиobj == null
.Ответы:
clazz.isAssignableFrom(Foo.class)
будет истинным, когда класс, представленныйclazz
объектом, является суперклассом или суперинтерфейсомFoo
.clazz.isInstance(obj)
будет истинным всякий раз, когда объектobj
является экземпляром классаclazz
.То есть:
всегда верно, пока
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
без повышения aClassCastException
. Другими словами, obj является экземпляромMyClass
или его подклассами.MyClass.class.isAssignableFrom(Other.class)
вернет true, еслиMyClass
это то же самое, или суперкласс или суперинтерфейс,Other
.Other
может быть классом или интерфейсом. Он отвечает истине, еслиOther
может быть преобразован вMyClass
.Небольшой код для демонстрации:
источник
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)
ISComparable.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.источник