试图访问另一个静态变量的静态变量

时间:2010-07-02 13:26:17

标签: java

我想知道以下代码是否安全。

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在静态范围内,它是否可以安全访问静态包?我是否使用延迟初始化技术会有什么不同吗?

我记得我遇到过一篇文章(我还是丢失了文章),讨论了静态变量初始化顺序的不确定性。我不确定静态变量的初始化顺序是否不确定,是否适用于上述情况?

4 个答案:

答案 0 :(得分:4)

我相信静态变量的非确定性初始化顺序(在不同的编译单元中)是C / C ++“特性”。在Java中,静态变量在加载类时初始化,并在声明顺序的单个类中初始化。因此,顺序是确定性的(至少在单线程环境中)。

这可以保证您打算执行的操作:首次引用GUIBundle时,类加载器会加载它并初始化bundle。对GUIBundle.getString()的调用仅在类初始化完成后才会发生。

答案 1 :(得分:1)

这很好用。我通过保持原理相同但使用不同的类来编译它(我不想打扰你的罐子......: - )。

显然有一些小问题,比如你声明你的String []需要

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

除此之外,它运作得很好。在其他静力学中使用静力学的关键是它们被声明的顺序。你不能这样做

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

答案 2 :(得分:1)

我觉得它非常安全,你看是因为什么时候

GUIBundle.getString
在你的JDialog子类中使用

,JVM将在调用方法getString之前完全初始化(参见java语言规范加载,链接和初始化)类GUIBundle,这将初始化类中的所有类(静态)初始值设定项GUIBundle。

编辑:在VM规范中阅读更多相关信息: http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16491

答案 3 :(得分:0)

对我而言,这是安全的。

bundleGUIBuilder加载后立即初始化,并且在第一次调用getString之前进行初始化。