Reputation: 42840
I was wondering, whether the following code are safe.
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")
};
}
Since cNames is within static scope, is it safe for it to access static bundle? Does it make any different whether I am using lazy initialization technique?
I remember I came across an article (I lost the article anyway) talking about nondeterministic of initialization order of static variables. I am not sure whether the nondeterministic of initialization order of static variables, applied to the above case?
Upvotes: 1
Views: 493
Reputation: 116306
I believe the nondeterministic initialization order of static variables (in different compilation units) is a C/C++ "feature". In Java, static variables are initialized when their class is loaded, and within a single class in their order of declaration. So the order is deterministic (at least in a single threaded environment).
This guarantees that what you intend to do should work: when GUIBundle
is first referenced, the classloader loads it and initializes bundle
too. The call to GUIBundle.getString()
happens only after the class initialization is done.
Upvotes: 4
Reputation: 24472
I think its perfectly safe, You see because the when
GUIBundle.getString
is used in your JDialog subclass, the JVM will completely initialize (see java language spec loading, linking and initialization) the class GUIBundle before calling the method getString on it, which will initialize all the class (static) initializers in the class GUIBundle.
Edit: Read more about this in VM spec: http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16491
Upvotes: 1
Reputation: 82589
That works just fine. I got it to compile by keeping the principle the same but using different classes (I didn't want to bother getting your jars... :-).
Obviously there are some small problems, like how you declare your String[] needs to be
private static final String[] cNames = new String[] {
GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue")
};
}
Other than that, it works just fine. The key to using statics in other statics is the order they're declared. You can't do this
static Foo b = a;
static Foo a = new Foo();
Upvotes: 1
Reputation: 114817
To me it's safe.
bundle
is initialized right after GUIBuilder
is loaded and therfore before getString
is called for the first time.
Upvotes: 0