2010-08-30 122 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