2010-03-31 3 views
50

Следующая отлично компилируется:InstanceOf - несовместимые типы операндов условного

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

Но это не:

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

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

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

+3

Если вы используете eclipse, взгляните на ответ SomeGuys. – Christian

ответ

48

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

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

Это указано в JLS 15.20.2 Type comparison operator instanceof:

RelationalExpression: 
     RelationalExpression instanceof ReferenceType 

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

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

(Number) "foo" 

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

("foo" instanceof Number) 

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

  • String является конечный класс
  • String не реализует Cloneable
  • Таким образом, вы можете 't do (Cloneable) aString
  • Поэтому вы также не можете сделать aString instanceof Cloneable
+1

Хотя этот ответ очень полезен, ему не хватает специального случая, упомянутого SomeGuy ниже, что было проблемой как для меня, так и для многих других. –

+11

Чтобы добавить к этому, если вам не хватает импорта для типа, который вы пытаетесь использовать в выражении 'instanceof', ваша среда IDE может вместо этого заставлять эту ошибку * жаловаться на недостающий импорт. Это может привести к запутанному «ложноположительному» вопросу, если у вас есть действующий класс, но он забыл его импортировать. – aroth

28

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

+0

Да, поэтому странно, что 'if (s instanceof String)' отлично, так как он всегда возвращает true ... – Perkins

+0

Почему это допускает обратное? Я имею в виду заданный класс, который реализует другой класс, 'X instanceof Y' * будет * компилироваться, даже если он всегда *' true'. Почему непоследовательность? – Maroun

+1

@MarounMaroun: Имейте в виду, что если 'X' равно null,' instanceof' вернет 'false' ... поэтому единственный раз, когда это было бы релевантно, было бы для непустых констант (которые в основном являются только строками) или 'new Foo()' выражения. Я думаю, что разумно, чтобы у него не было специального правила в спецификации языка. –

148

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

+12

Спасибо. Вы только что исправили мою проблему. Надеюсь, затмение будет исправлено в будущем. – kevinarpe

+16

ПОЛЬЗОВАТЕЛИ ECLIPSE ПРОЧИТАЙТЕ ЭТО ОТВЕТ! – Shane

+1

Ahhhh yes @Shane, мои усталые глаза нуждались в этом, чтобы меня кричали. Благодарю. – Vinnyq12

Смежные вопросы