web-dev-qa-db-fra.com

instanceof - types d'opérandes conditionnels incompatibles

Ce qui suit compile très bien:

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

Mais cela ne veut pas:

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

Une erreur de compilation est levée.

Quel est le problème?

53
java_geek

Une incarnation plus flagrante de votre problème est la suivante:

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

Ceci est spécifié dans JLS 15.20.2 Opérateur de comparaison de types instanceof :

RelationalExpression:
       RelationalExpression instanceof ReferenceType

Si une conversion de RelationalExpression en ReferenceType serait rejetée en tant que erreur de compilation, puis l'expression relationnelle instanceof produit également une erreur de compilation. Dans une telle situation, le résultat de l'expression instanceof ne pourrait jamais être vrai.

C'est-à-dire, puisque cette expression cast génère une erreur de temps de compilation:

(Number) "foo"

doit donc cette expression:

("foo" instanceof Number)

Votre cas est un peu plus subtil, mais le principe est le même:

  • String est une classe finale
  • String n'implémente pas Cloneable
  • Vous ne pouvez donc pas faire (Cloneable) aString
  • Par conséquent, vous ne pouvez pas non plus aString instanceof Cloneable
51
polygenelubricants

Un problème connexe que j'ai rencontré récemment (et qui m'a amené à cette page, avant de comprendre ce qui se passait) est que l'environnement Eclipse peut signaler "des types d'opérandes conditionnels incompatibles" dans une expression "instanceof" à tort en raison d'un instruction 'import' manquante pour le type à droite de 'instanceof'. J'ai passé un certain temps à essayer de comprendre comment les types en question pouvaient éventuellement être incompatibles avant de comprendre qu'une importation manquante était à l'origine de tout le problème. Espérons que cette information fasse gagner du temps à quelqu'un.

151
Some Guy

Le compilateur sait que String est une classe finale et n'implémente pas Cloneable. Aucune instance de String ne peut donc jamais être une instance de Cloneable. Cela vous empêche de penser que vous avez un test significatif alors qu'en réalité, il sera toujours imprimé "faux".

28
Jon Skeet