2010-03-31 11 views
50

Di seguito compila bene:instanceof - tipi di operando condizionale incompatibili

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

ma questo non significa:

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

un errore di compilazione viene generata.

Qual è il problema?

+3

se si utilizza eclissi, dare un'occhiata alla risposta SomeGuys. – Christian

risposta

48

Un'incarnazione più evidente del problema è il seguente:

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

Questo è specificato in 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.

Cioè, dal momento che questa espressione getto genera un errore di compilazione:

(Number) "foo" 

così deve questa espressione:

("foo" instanceof Number) 

Il tuo caso è un po 'più sottile, ma il principio è lo stesso:

  • String è una classe finale
  • String non implementa Cloneable
  • Quindi si può 't do (Cloneable) aString
  • Pertanto non è possibile fare aString instanceof Cloneable
+1

Sebbene questa risposta sia molto utile, manca il caso speciale menzionato da SomeGuy in basso, che era il problema sia per me che apparentemente molti altri. –

+11

Giusto per aggiungere a questo, se ti manca un'importazione per il tipo che stai cercando di usare nell'espressione 'instanceof', l'IDE potrebbe segnalare questo errore * invece * di lamentarsi dell'importazione mancante. Questo può portare a un tipo di problema "falso positivo" confuso se hai una classe valida ma hai dimenticato di importarla. – aroth

28

Il compilatore sa che String è una classe finale e non implementa Cloneable. Quindi nessuna istanza di String può mai essere un'istanza di Cloneable. Ti impedisce di pensare di avere un test significativo quando in realtà stamperà sempre "false".

+0

Sì, ed è per questo che è strano che "if (s instanceof String)" vada bene, poiché restituisce sempre true ... – Perkins

+0

Perché consente il contrario? Voglio dire data una classe che implementa un'altra classe, 'X instanceof Y' * compila * anche se è * always *' true'. Perché l'incoerenza? – Maroun

+1

@MarounMaroun: Ricorda che se 'X' è nullo,' instanceof' restituirà 'false' ... quindi l'unica volta in cui sarebbe rilevante sarebbe per le costanti non nulle (che sono fondamentalmente solo stringhe) o 'nuove espressioni Foo()'. Penso che sia ragionevole non avere una regola speciale nelle specifiche del linguaggio. –

148

Una questione collegata che ho incontrato di recente (e che mi ha portato a questa pagina, prima di capire che cosa stava succedendo) è che l'ambiente Eclipse può segnalare "incompatibili tipi di operando condizionali" in un ' istanza di espressione erroneamente dovuta a una dichiarazione di "importazione" mancante per il tipo a destra dell '"instanceof". Ho passato un po 'di tempo cercando di capire come i tipi in questione potrebbero essere incompatibili prima di capire che un'importazione mancante stava causando l'intero problema. Speriamo che questa informazione salvi qualcuno da qualche tempo.

+12

Grazie. Hai appena risolto il mio problema. Spero che eclipse si risolverà in futuro. – kevinarpe

+16

Gli utenti di ECLIPSE LEGGONO QUESTA RISPOSTA! – Shane

+1

Ahhhh si, @Shane, i miei occhi stanchi avevano bisogno che mi venissero gridati. Grazie. – Vinnyq12

Problemi correlati