2010-08-30 95 views
12

我有点困惑:我有一个函数,它将一个对象作为参数。但编译器不会抱怨,如果我只是传递一个基元,甚至可以将布尔基元识别为布尔对象。为什么?java:布尔instanceOf布尔?

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

注意一个布尔值从来不是布尔的一个实例。你永远不能将一个原语传递给instanceof操作符。你的布尔原语从来没有进入这个方法,当调用发生和方法调用转换发生时,会发生装箱! – Mishax 2013-03-19 06:10:52

回答

29
由于

原始 'true' 将是​​Boolean和作为Object

+3

(+1)这里有一些[文档随它去](http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html) – 2010-08-30 13:22:01

+0

进一步阅读:http:///download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html @jpegzz,如果你运行1.4.x – 2010-08-30 13:22:08

+0

有趣:)代码不会编译好吧,文档只建议如果真的需要使用自动装箱,所以我不会。但很高兴知道这不是一个错误,而是一个功能:) – epegzz 2010-08-30 13:27:14

2

方法的这一部分:

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

可以用

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

的实例是否与OP的代码行为不同。 'null'会返回“invalid”,因为'null'不是'Boolean'的实例(你在上面第一个代码中的OP代码中缺少那行代码); “不知道”永远不会被退回(通过原始代码)。如果没有该行,当值为空时,第一个代码会抛出NPE。 – 2010-08-30 13:33:07

+0

@Carlos,我永远不会记得'instanceof'是否返回true或false,所以我通常通过事先检查null来避免这种情况。 – 2010-08-30 14:07:56

3

像以前的答案说来代替,它被称为自动装箱。

事实上,在编译时,javac会将您的boolean原始值转换为Boolean对象。请注意,通常情况下,反向转换可以产生很奇怪的NullPointerException因为,作为一个例子,下面的代码:

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

你可以看看JDK documentation更多的相关信息。

+7

你是不是指'布尔b = null;'? – mlvljr 2010-11-13 21:45:58

+1

我想你的意思是'布尔b = null;'而不是'布尔b = null;'。注意首都。 – 2017-06-11 18:40:12