2010-03-31 10 views
50

El siguiente compila bien:instanceof - tipos incompatibles de operando condicional

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

pero esto no significa: se lanza

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

un error de compilación.

¿Cuál es el problema?

+3

si está utilizando eclipse, eche un vistazo a la respuesta de SomeGuys. – Christian

Respuesta

48

una encarnación más flagrante de su problema es el siguiente:

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

Esto se especifica en 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.

Eso es, ya que esta expresión de conversión genera un error de tiempo de compilación:

(Number) "foo" 

así que debe esta expresión:

("foo" instanceof Number) 

su caso es un poco más sutil, pero el principio es el mismo:

  • String es una clase final
  • String no implementa Cloneable
  • lo tanto, puede 't hacer (Cloneable) aString
  • Por lo tanto, también no se puede hacer aString instanceof Cloneable
+1

Aunque esta respuesta es muy útil, carece del caso especial mencionado por SomeGuy a continuación, que fue el problema tanto para mí como para muchos otros. –

+11

Solo para agregar a esto, si le falta una importación del tipo que está tratando de usar en la expresión 'instanceof' su IDE puede generar este error * en vez * de quejarse sobre la importación que falta. Esto puede conducir a un tipo confuso de 'falso positivo' si tiene una clase válida pero se olvidó de importarla. – aroth

28

El compilador sabe que String es una clase final y no implementa Cloneable. Entonces ninguna instancia de String puede alguna vez ser una instancia de Cloneable. Te está impidiendo pensar que tienes una prueba significativa cuando en realidad siempre imprimirá "falso".

+0

Sí, por lo que es extraño que 'if (s instanceof String)' esté bien, ya que siempre devuelve verdadero ... – Perkins

+0

¿Por qué permite lo contrario? Me refiero a una clase que implementa otra clase, 'X instanceof Y' * will * compile incluso si es * always *' true'. ¿Por qué la inconsistencia? – Maroun

+1

@MarounMaroun: Tenga en cuenta que si 'X' es nulo,' instanceof' devolverá 'false' ... así que el único momento en el que sería relevante sería para las constantes no nulas (que básicamente son solo cadenas) o 'nuevas expresiones de Foo()'. Creo que es razonable que no se tenga una regla especial en la especificación del idioma. –

148

Un tema relacionado que me he encontrado recientemente (y que me llevó a esta página, antes de que me di cuenta de lo que estaba pasando) es que el entorno Eclipse puede reportar "incompatibles tipos de operando condicionales" en una " instanceof 'expresión erróneamente debido a una declaración de' importación 'faltante para el tipo a la derecha de' instanceof '. Pasé un tiempo tratando de descubrir cómo los tipos en cuestión podrían ser incompatibles antes de descubrir que una importación faltante estaba causando todo el problema. Con suerte, esta información le ahorrará a alguien algo de tiempo.

+12

Gracias. Usted acaba de arreglar mi problema. Espero que Eclipse lo solucione en el futuro. – kevinarpe

+16

USUARIOS DE ECLIPSE ¡LEA ESTA RESPUESTA! – Shane

+1

Ahhhh sí @Shane, mis ojos cansados ​​necesitaban que me gritaran. Gracias. – Vinnyq12

Cuestiones relacionadas