2012-10-18 50 views
7

在我們的一些公司的項目代碼,我經常看這樣的事情:使用Boolean.FALSE/.TRUE初始化布爾值 - 爲什麼?

boolean foo = Boolean.FALSE; 

除了這個事實,據我所知我只有在所有(如Pascal沒有隨機值)來初始化在Java中的局部變量和除事實上,特別是對於我經常想要初始化的布爾值來說,我在這裏錯過了什麼?爲什麼不:

boolean foo = false; 

我不明白。像PMD和Findbugs這樣的代碼分析工具也會標記它。但爲什麼?

編輯: 沒有真正瞭解字節碼,除了在那裏我創建了一個示例類並反編譯它。該Boolean.FALSE去:

0: getstatiC#15 // Field java/lang/Boolean.FALSE:Ljava/lang/Boolean; 
3: invokevirtual #21 // Method java/lang/Boolean.booleanValue:()Z 
6: istore_1 

的「假」變去:

0: iconst_1 
1: istore_1 

所以不知道太多關於這一點,我想這條語句,意味着有更多的時間來執行這樣這不僅是錯誤的,而且從長遠來看也會變慢。

+0

教條主義,我想。 –

+1

第一個只是錯誤的用法。儘管你可能會認爲任何可能使代碼更加冗長的風格幾乎都是Java慣用的**。 –

+0

這可能是爲了確保如果布爾(後端)有變化,這將確保代碼始終工作..?它看起來很奇怪。 – OmniOwl

回答

12
boolean foo = Boolean.FALSE; 

這是一個奇怪且不必要的複雜代碼,由可能不太熟悉Java的人編寫。你不應該寫這樣的代碼,而且PMD和FindBugs是正確的。

Boolean.FALSEjava.lang.Boolean對象獲取自動拆箱;編譯器基本上是將這種以:

boolean foo = Boolean.FALSE.booleanValue(); 

我沒有在Java中初始化變量在所有...

成員變量並不需要明確初始化;如果你不這樣做,它們將被初始化爲一個默認值(對於boolean,這是false)。局部變量需要顯式初始化;如果您嘗試在不初始化的情況下使用局部變量,編譯器會給您一個錯誤。

1

儘管第1種方法在1.4或更早版本的JVM上不起作用,但確實沒有什麼區別。第一個更復雜,因爲它從布爾對象中獲取靜態值,然後依靠自動裝箱(在1.5中引入)將其從布爾對象更改爲布爾基元),儘管我無法想象它會以任何速度區別。

但是總的來說,如果我們假定你是一個特定的初始值的變量,那麼我會建議它初始化,而不是僅僅宣佈它,因爲它使代碼更易讀。

+0

實際上有區別。 'Boolean.FALSE'是一個布爾對象,'false'是一個布爾類型的基元。 – jrajav

+0

嗨Kiyura,發佈後我意識到這一點,並編輯糾正它。只是讓這項任務變得更加複雜。 – AntonyM

+0

@Kiyura是的,但由於它被分配到原始布爾值,它將立即被拆箱,所以最終結果是相同的。如果編譯器優化了這一點,我甚至不會感到驚訝。 –

2

兩者都是相同的。但boolean foo = false;就夠了。

2

的風格來使用自動拆箱Boolean常數其實與整體oververbosity特有的許多Java項目以及網格。例如:

public boolean isItOrIsItNotTheValueWeExpect(String aStringParameterThatCouldBeNull) { 
    boolean booleanReturnValue = Boolean.FALSE; 
    if (aStringParameterThatCouldBeNull != null) { 
    if (aStringParameterThatCouldBeNull.length() > 3) { 
     booleanReturnValue = Boolean.TRUE; 
    } 
    else { 
     booleanReturnValue = Boolean.FALSE; 
    } 
    } 
    else if (aStringParameterThatCouldBeNull == null) { 
    booleanReturnValue = Boolean.TRUE.booleanValue(); 
    } 
    return booleanReturnValue; 
} 

顯然,上面的代碼將是更優選的本不可讀亂七八糟:

public boolean validate(String s) { 
    return s == null? true : s.length() > 3; 
} 

三元操作者的非常發生被認爲是侵和某些項目甚至它由標記CheckStyle的。

如果您的項目符合這些風格指南,那可能會證明您的可疑代碼行。

+0

我個人發現三元運算符功能太強大了 - 因爲它可以在程序流程中引入一個分支,而不用明確標記爲「if」關鍵字。簡潔並不意味着可維護性。 –

+0

@ThorbjørnRavnAndersen你去那裏,你應該啓用對三元運算符的CheckStyle規則:) –

+0

哦,如果有人把我的三元體系帶走離開我,我會哭幾天。 – yshavit

2

沒有很好的理由這樣做,它可能只是一個新手Java程序員。我不會太擔心,只需用假來代替。

與此同時,通常情況下,如果不是始終如此安排代碼,以至於從不聲明一個變量,而這些變量沒有最終值,即使對象不可變,這使得它們更易於思考。 x的價值是什麼?相比於調用foo()和bar()之間的x的值是多少?第一個答案通常更容易回答。這要求你按照你可能不習慣的方式來分班,但我建議至少嘗試一下。