оператор instanceof - несовместимые типы операндов условного


следующие компиляции отлично:

  Object o = new Object();
  System.out.println(o instanceof Cloneable);

но это не так:

  String s = new String();
  System.out.println(s instanceof Cloneable);

возникает ошибка компилятора.

в чем проблема?

3 51

3 ответа:

более вопиющим воплощением вашей проблемы является следующее:

if ("foo" instanceof Number)
   // "Incompatible conditional operand types String and Number"

это указано в JLS 15.20.2 оператор сравнения типов instanceof:

RelationalExpression:
       RelationalExpression instanceof ReferenceType

если бросок RelationalExpression до ReferenceType будет отклонен как ошибка времени компиляции, то instanceof реляционное выражение также создает ошибку времени компиляции. В такой ситуации, результат instanceof выражение никогда не может быть правдой.

то есть, поскольку это выражение cast генерирует ошибку времени компиляции:

(Number) "foo"

так должно быть это выражение:

("foo" instanceof Number)

ваш случай немного более тонкий, но принцип тот же:

  • String это последний класс
  • String не реализует Cloneable
  • поэтому вы не можете сделать (Cloneable) aString
  • поэтому и вы не можете сделать aString instanceof Cloneable

связанная с этим проблема, с которой я столкнулся недавно (и которая привела меня на эту страницу, прежде чем я понял, что происходит), заключается в том, что среда Eclipse может сообщать о "несовместимых типах условных операндов" в выражении "instanceof" ошибочно из-за отсутствующего оператора "import" для типа справа от "instanceof". Я потратил некоторое время, пытаясь выяснить, как рассматриваемые типы могут быть несовместимы, прежде чем выяснить, что отсутствующий импорт вызывает весь проблема. Надеюсь, эта информация сэкономит кому-то некоторое время.

компилятор знает, что String является конечным классом и не реализует Cloneable. Так что ни один экземпляр строки не может когда-нибудь быть экземпляр Cloneable. Это мешает вам думать, что у вас есть значимый тест, когда на самом деле он всегда будет печатать "false".