Были представлены несколько правильных ответов, но есть еще несколько методов: Class.isAssignableFrom()
и просто попытка сотворить объект (который может выдать ClassCastException
).
Возможные способы суммированы
Давайте подведем итоги возможных способов проверить, является ли объект obj
экземпляром типа C
:
// Method #1
if (obj instanceof C)
;
// Method #2
if (C.class.isInstance(obj))
;
// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
;
// Method #4
try {
C c = (C) obj;
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
// Method #5
try {
C c = C.class.cast(obj);
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
Различия в null
обработке
Существует разница в обработке null
:
- В первых двух методах выражения оцениваются как
false
, если obj
равно null
(null
не является экземпляром чего-либо).
- Третий метод, очевидно, выдаст
NullPointerException
.
- 4-й и 5-й методы наоборот принимают
null
, потому что null
может быть приведен к любому типу!
Запомните: null
не является экземпляром любого типа, но может быть приведен к любому типу.
Примечания
Class.getName()
не должен использоваться для выполнения "is-instance-of" теста, поскольку объект не относится к типу C
, но является его подклассом, он может иметь совершенно другой имя и пакет (поэтому имена классов, очевидно, не будут совпадать), но он по-прежнему имеет тип C
.
- По той же причине наследования
Class.isAssignableFrom()
не является симметричным :
obj.getClass().isAssignableFrom(C.class)
вернет false
, если тип obj
является подклассом C
.