2010-07-02 169 views
1

我想知道下面的代碼是否安全。試圖訪問另一個靜態變量的靜態變量

public class GUIBundle { 

    // The technique known as the initialization on demand holder idiom, 
    // is as lazy as possible. 
    // http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom 
    //private static class BundleHolder { 
    // private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui"); 
    //} 
    private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui"); 

    private GUIBundle() { 
    } 

    public static String getString(String key) { 
     // return BundleHolder.bundle.getString(key); 
     return bundle.getString(key); 
    } 
} 

public class SellPortfolioChartJDialog extends javax.swing.JDialog { 

    private static final String[] cNames = new String[] { 
     GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue") 
    }; 
} 

由於CNAMES是靜態的範圍內,它是安全的它來訪問靜態捆綁?是否使用惰性初始化技術有什麼不同?

我記得我遇到過一篇文章(我遺失了文章),談論靜態變量的初始化順序的不確定性。我不確定靜態變量的初始化順序的不確定性是否適用於上述情況?

+0

你的API返回'的String []' - 這無論如何都不會編譯。我認爲我理解了這個主題,如果你糾正了你的代碼,我認爲這會起作用(安全)。 – 2010-07-02 13:40:22

+0

@ring他正在建造一個帶有1個字符串的String []。 – corsiKa 2010-07-02 13:42:32

+0

getString方法應該有「返回bundle.getString(key)」和一個';'爲cNames是失蹤,...它編譯,我猜是因爲評論代碼的錯字:) – naikus 2010-07-02 13:43:22

回答

4

我相信靜態變量(在不同的編譯單元中)的非確定性初始化順序是一個C/C++「功能」。在Java中,靜態變量在其類加載時被初始化,並且在它們的聲明順序中處於單個類中。所以順序是確定性的(至少在單線程環境中)。

這保證你打算做的事情應該工作:當第一次引用GUIBundle時,類加載器加載它並初始化bundle。對GUIBundle.getString()的調用僅在類初始化完成後纔會發生。

+0

不,初始化順序可能是不確定的。 Joshua Bloch有更多信息。 – DJClayworth 2010-07-02 16:39:13

+0

@DJClayworth,你能否提供更具體的參考?在Effective Java中我找不到這方面的任何細節。 – 2010-07-02 20:14:06

+0

我找不到。你能提供參考嗎? – 2010-07-03 18:36:02

0

對我來說這是安全的。

bundleGUIBuilder加載之後立即初始化,因此第一次調用getString之前。

1

這工作得很好。我通過保持原則相同,但使用不同的類(我不想打擾讓你的罐子...... :-)。

顯然,有一些小問題,比如如何你宣佈你的String []需要爲

private static final String[] cNames = new String[] { 
     GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue") 
    }; 
} 

除此之外,它工作得很好。在其他靜態圖中使用靜態圖的關鍵是它們聲明的順序。你不能這樣做

static Foo b = a; 
static Foo a = new Foo(); 
1

我認爲它的絕對安全,你看,因爲當

GUIBundle.getString 

在你的JDialog子類時,JVM將完全初始化(見Java語言規範裝載,連接和初始化)之前調用的類GUIBundle方法getString,它將初始化類GUIBundle中的所有類(靜態)初始化器。

編輯:瞭解更多關於這VM規格:`String`和你試圖讓 http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16491