2016-03-01 164 views
0

我有一個小的類,它包含一個靜態最終變量和靜態函數:靜態函數返回錯誤的值?

public class GlobalConstants { 
    public static final boolean ONLINE = true; 

    public static boolean isOnline(){ 
     return ONLINE; 
    } 
} 

(當然有一點重複代碼,但請忽略)

我打包我的程序一個可運行的罐子,並得到奇怪的結果:

log.debug(GlobalConstants.isOnline()); //prints false 
log.debug(GlobalConstants.ONLINE); //prints true 

我希望他們都打印「真」。

是java編譯器做了一個優化,導致這種奇怪的行爲,或者我錯過了什麼?

+0

您未設置isOnline,您正在設置ONLINE。 – durbnpoisn

+4

你真的運行過這個最簡單的例子嗎?也許你從代碼中刪除了一些重要的部分?我創建了一個項目並執行你的代碼。它運行良好。 –

+0

@Neuron不,它是一個大程序的一部分,但是兩個log.debug行都在程序啓動時調用,並相互調用。請注意,在eclipse中它工作正常,只有當我將它打包在可運行的jar中時,log.debug行會打印錯誤的值。 –

回答

0

爲幫助傢伙們歡呼!發現問題,它似乎是我的本地Maven存儲庫丟失了持有GlobalConstants類的庫的副本。該類作爲依賴包含在可運行jar中。但是這並不能解釋「false,true」輸出,除非GlobalConstants.ONLINE被java編譯器優化(因爲它是最終的)而被轉換爲布爾值。它仍然讓我困惑了一下。

[更新] 我反編譯我的課,確實:

System.out.println(GlobalConstants.ONLINE); 
System.out.println(GlobalConstants.isOnline()); 

由Java編譯器轉換在:

System.out.println(true); 
System.out.println(GlobalConstants.isOnline()); 

現在是所有清楚,這解釋了我原來的職位結果。因爲即使它使用錯誤的類版本,它也應該產生相同的結果(true,true)。但是,因爲Java編譯器有魔力,所以它可能返回true,false。

1

看看this project我設置了您的代碼。它的工作方式和預期的一樣,你的錯誤必須存在於你刪除的代碼的某些部分,以簡化你的代碼示例。

並始終認爲您的靜態代碼必須執行。如果您從靜態上下文中調用上述代碼,則某些循環依賴可能會導致某些靜態變量在被調用之前未被初始化

+0

我的確同意,它不應該返回真實和錯誤,而是真實的,使世界上的所有感覺;-)因此,我的問題。我懷疑我可能會做出錯誤的事情。當我發現什麼時,我會發表評論。 –