Instanceof - несовместимые условные типы операндов
Следующие компилируемые файлы:
Object o = new Object();
System.out.println(o instanceof Cloneable);
Но это не так:
String s = new String();
System.out.println(s instanceof Cloneable);
Ошибка компилятора.
В чем проблема?
Ответы
Ответ 1
Более вопиющее воплощение вашей проблемы заключается в следующем:
if ("foo" instanceof Number)
// "Incompatible conditional operand types String and Number"
Это указано в JLS 15.20.2 Оператор сравнения типов instanceof
:
RelationalExpression:
RelationalExpression instanceof ReferenceType
Если преобразование RelationalExpression в ReferenceType будет отклонено как ошибка времени компиляции, то реляционное выражение instanceof
также создает ошибку времени компиляции. В такой ситуации результат выражения instanceof
никогда не может быть правдой.
То есть, поскольку это выражение выражения генерирует ошибку времени компиляции:
(Number) "foo"
так должно быть это выражение:
("foo" instanceof Number)
Ваше дело немного более тонкое, но принцип тот же:
-
String
- это последний класс
-
String
не реализует Cloneable
- Поэтому вы не можете сделать
(Cloneable) aString
- Поэтому вы также не можете сделать
aString instanceof Cloneable
Ответ 2
Связанная с этим проблема, с которой я столкнулся недавно (и которая привела меня на эту страницу, прежде чем я выяснил, что происходит), заключается в том, что среда Eclipse может ошибочно сообщать "Несовместимые условные типы операндов" в выражении "instanceof" из-за отсутствующего оператора "import" для типа справа от "instanceof". Я потратил некоторое время, пытаясь понять, как типы, о которых идет речь, могут быть несовместимыми, прежде чем выяснять, что недостающий импорт вызывает всю проблему. Надеюсь, эта информация немного спасет кого-нибудь.
Ответ 3
Компилятор знает, что String
является окончательным классом и не реализует Cloneable
. Таким образом, ни один экземпляр String никогда не может быть экземпляром Cloneable
. Это мешает вам подумать, что у вас есть осмысленный тест, когда на самом деле он всегда будет печатать "ложь".