2010-08-30 10 views
12

Je suis un peu confus: j'ai une fonction qui prend un objet comme argument. Mais le compilateur ne se plaint pas si je ne fais que passer une primitive et même reconnaître une primitive booléenne comme objet booléen. Pourquoi est-ce si?java: boolean instanceOf Boolean?

public String test(Object value) 
{ 
    if (! (value instanceof Boolean)) return "invalid"; 
    if (((Boolean) value).booleanValue() == true) return "yes"; 
    if (((Boolean) value).booleanValue() == false) return "no"; 
    return "dunno"; 
} 

String result = test(true); // will result in "yes" 
+2

Notez qu'un booléen n'est JAMAIS une instance de Boolean. Vous ne pouvez jamais passer une primitive à l'opérateur instanceof. Votre primitif booléen n'est jamais entré dans cette méthode, la boxe est arrivée quand l'invocation s'est produite et la conversion de l'invocation de la méthode a eu lieu! – Mishax

Répondre

29

Parce que primitive 'true' sera Autoboxed-Boolean et qui est un Object.

+3

(+1) Et voici quelques [documentation pour aller avec elle] (http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html) –

+0

Plus de lecture: http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html @jpegzz, le code ne compilerait pas si vous utilisiez 1.4.x –

+0

intéressant :) Eh bien, les docs suggèrent seulement de utiliser autoboxing si vraiment nécessaire, donc je ne vais pas. Mais il est bon de savoir que ce n'est pas un bug mais une fonctionnalité :) – epegzz

2

Cette partie de la méthode:

if (((Boolean) value).booleanValue() == true) return "yes"; 
    if (((Boolean) value).booleanValue() == false) return "no"; 
    return "dunno"; 

pourrait être remplacé par

if (value == null) return "dunno"; 
    return value ? "yes" : "no"; 
+0

qui n'est pas identique au comportement du code OP. 'null' retournera" invalide "puisque' null' n'est pas une instance de 'Boolean' (vous avez manqué cette ligne du code d'OP dans votre premier code ci-dessus); "ne sais pas" ne sera jamais retourné (par le code original). Sans cette ligne, votre premier code lancerait un NPE lorsque la valeur est 'null'. –

+0

@Carlos, je ne peux jamais me souvenir si 'instanceof' renvoie true ou false avec tous les nulls, donc j'évite habituellement le cas en vérifiant null avant. –

3

Comme les réponses précédentes dit, ça s'appelle autoboxing.

En fait, au moment de la compilation, javac transformera votre valeur primitive boolean en un objet Boolean. Notez que généralement, transformation inverse peut générer NullPointerException très étrange raison, à titre d'exemple, le code suivant:

boolean b = null; 
if(b==true) <<< Exception here ! 

Vous pouvez jeter un oeil à JDK documentation pour plus d'infos.

+7

Voulez-vous dire 'Boolean b = null;' ?? – mlvljr

+1

Je pense que vous vouliez dire 'Boolean b = null;' au lieu de 'boolean b = null;'. Notez la capitale. –