I was going through this topics:
In what order do static initializer blocks in Java run?
Java Static Initialization Order
And I don't understand if we have a constructors, where we can put some logic, such as dealing with exceptional situations, why we need initialization blocks, which code we can also move to constructor ?
If the answer is that in some cases we need to initialize some resources before constructor runs would you help me with some examples, so I could fully see the picture.
One example of a time when you'd use (and I have used) static initialization blocks is to initialize a collection of elements. For example, if I have some set of parsers that are stored in a static map:
private static Map<String, Parser> parsers = new HashMap<String, Parser>();
I may use a static initialization block to populate the members of this map:
static {
parsers.put("node", new NodeParser());
parsers.put("tree", new TreeParser());
parsers.put("leaf", new LeafParser());
//etc.
}
I would do this because I want the map to be static rather than part of a particular object, or if I only want there to be one of these maps (maybe I only need one).
The difference between this and a constructor is the constructor is called at object instantiation whereas the static initialization block will be called when the class is loaded.
That is, if you call
MyClass.parsers.get("node");
The MyClass constructor is never called so if you waited to initialize the parsers map until the constructor, the above call would return null.
why we need initialization blocks
For instance initialization blocks, I can only think on two cases:
When creating an anonymous class:
Runnable runnable = new Runnable() {
int x;
//initialization block here
{
//IMO this is such odd design, it would be better to not
//create this as an anonymous class
x = outerClassInstance.someMethod();
}
#Override
public void run() {
//write the logic here...
}
};
When using double brace initialization (if the class is not marked final):
List<String> stringList = new ArrayList<>() {
{
add("Hello");
add("world");
}
};
System.out.println(stringlist);
//prints [Hello, world]
For static initialization blocks, there are two cases:
When defining the data for a static field. This is covered in #ChrisThompson's answer.
When initializing a constant (static final) field from an external source, like the result of some computation.
class Foo {
public static final boolean DEBUG;
static {
DEBUG = getDebugMode();
}
private static boolean getDebugMode() {
//code to open a properties file, read the DEBUG property
//and return the value
}
}
Related
This question already has answers here:
Static Initializers And Static Methods In Java
(4 answers)
Closed 4 years ago.
Why do we use static blocks when we can use static methods for initializing static variables? What difference does it make? What is the logic to this.
I assume you are referring to static initializer blocks?
static { ... }
Static initializer blocks and static methods are both required because they do different things.
Static initializer blocks are blocks for initializing the class. They are run exactly once, when the class is loaded. They don't return anything, and can't throw a checked exception because there is no way to declare throws.
In fact, a static field with an initializer:
static int a = 0;
Is actually converted to a field declaration and a static initializer block:
static int a;
static {
a = 0;
}
You can assign zero or more static final variables in a static initializer, provided they have not already been assigned.
Static methods can be invoked at any time. They can return a value, and throw checked exceptions. You cannot assign static final variables in a static method (although you can assign non-final static variables).
You are thinking about very 2 different ideas about initialize object. for example:
class A {
static Map<String, String> map;
static {
map = new HashMap<String, String>();
}
public static void initializeMap() {
map = new HashMap<String, String>();
}
public static void insert(String key, String value) {
map.put(key, value);
}
}
If we use static initializer block, the very first time you use any static method (i.e: insert), it will run static block first. And by doing this, you are safe for concurrency control. i.e: there are multiple threads try to call method insert at very beginning, Java will only run initialize block once.
Using static method for initialize such as initializeMap in this case, the advantage is you move the control of when run init to your own program. Maybe your class should not init ASAP but only your program told to do so. Other advantage is you can control the return value, or raise exception if needed (you cannot raise exception in static initializer block).
Note that the static method above is not safe and should not call concurrently. Other word, you should make sure only one thread call that method for initialize map. Otherwise, you must add lock to control multiple thread access.
Some other notes about advantages of using static initializer block:
Handle concurrency access automatically provided by Java.
Some program we don't know exactly where to put static method, so using static initializer is a safe choice.
Some complex initialize cannot be done in one line, so static initializer is the only choice.
You have static blocks to do more complex initialization, like for instance this upload queue where you just want to make sure a directory exists.
static {
File f = new File(getUploadDir());
if(!f.exists()) {
//noinspection ResultOfMethodCallIgnored
f.mkdir();
}
}
You can also use it to set some properties on static objects. Here's an example:
private static final SimpleDateFormat mDateTimeFormat = new
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
static {
mDateTimeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
I've been wondering about singletons in Java. By convention, a singleton is set up something like this:
private static MyClass instance = null;
public static MyClass getInstance(){
if (instance == null){
instance = new MyClass();
}
return instance;
}
private MyClass(){}
Recently I've switched to using the following:
public static final MyClass instance = new MyClass();
private MyClass(){}
This is a lot shorter, faster as there's no null-check, and typing MyClass.instance feels nicer to me than typing MyClass.getInstance(). Is there any reason why the second is not the mainstream way to do this?
The first version creates the instance the first time it is actually needed, while the second (the shorter) runs the constructor as soon as the class is initialized
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant
variable (§4.12.4).
T is a top level class (§7.6), and an assert statement (§14.10)
lexically nested within T (§8.1.3) is executed. [...]
Invocation of certain reflective methods in class Class and in
package java.lang.reflect also causes class or interface initialization.
The initialization upon first usage is a performance improvement that may speed up the startup of the application if the code in the constructor makes expensive operations. On the other hand, the second version is straightforward to read and is automatically thread-safe.
Anyway, the state of the art is not creating singleton in either ways: for a bunch of KB you can get dependency injection libraries that make it working for you, and also handle more complex scenarios (for example look at Spring and AOP-backed injection).
Note: the first version is not thread safe in the pasted snippet
The way you have first described is known as lazy instantiation, i.e the object will only be created when it is first called. This method is not thread-safe as it is possible for a second thread to create a second instance.
If you read the following book:
Effective Java by Joshua Bloch
He explains that the best implementation of the singleton pattern is through the use of an Enum :
public enum Singleton {
INSTANCE;
public void doSomething() {
...
}
}
Then you would call your singleton through the Enum as follows:
public class Test {
public void test(){
Singleton.INSTANCE.doSomething();
}
}
This fits nicely with what you are saying in terms of it looks nicer and shorter to write but also guarantees there can never be a second instance.
I can think of two reasons:
The first is Encapsulation: you might have second thoughts about how and when your singleton is initialized, after your class has been exposed to client code. And an initialization method gives you more freedom as to changing your strategy later on. For example you might change your mind and decide to use two different constructors instead of one, according to another static variable's value at runtime. With your solution you're bound to using just one constructor at the time your class is loaded into memory, whereas with getInstance() you can change the initialization logic without affecting the interface to the client code.
The second is Lazy Initialization : with the conventional singleton implementation the MyClass object is loaded into memory only when needed by the client code for the first time. And if the client code doesn't need it at all, you save on the memory allocated by your application. Note that whether your singleton is needed or not might not be certain until the program runs. For example it might depend on the user interaction with the program.
However the Lazy Initialization is not something you might necessarily want. For example if you're programming an interactive system and the initialization of your singleton is time consuming, it might actually be better to initialize it when the program is loading rather than when the user is already interacting with it, cause the latter might cause a latency in your system response the first time getInstance() is called. But in this case you can just have your instance initialized with the public method as in:
private static MyClass instance = getInstance();
The best way to synchronize the threads is using Double Checked (to ensure that only one thread will enter the synchronized block at a time and to avoid obtaining the lock every time the code is executed).
public class DoubleCheckLocking {
public static class SearchBox {
private static volatile SearchBox searchBox;
// private attribute of this class
private String searchWord = "";
private String[] list = new String[]{"Stack", "Overflow"};
// private constructor
private SearchBox() {}
// static method to get instance
public static SearchBox getInstance() {
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
return searchBox;
}
}
Reflection: Reflection can be caused to destroy singleton
property of singleton class, as shown in following example:
// Java code to explain effect of Reflection
import java.lang.reflect.Constructor;
// Singleton class
class Singleton
{
// public instance initialized when loading the class
public static Singleton instance = new Singleton();
private Singleton()
{
// private constructor
}
}
public class GFG
{
public static void main(String[] args)
{
Singleton instance1 = Singleton.instance;
Singleton instance2 = null;
try
{
Constructor[] constructors =
Singleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors)
{
// Below code will destroy the singleton pattern
constructor.setAccessible(true);
instance2 = (Singleton) constructor.newInstance();
break;
}
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("instance1.hashCode():- "
+ instance1.hashCode()); //366712642
System.out.println("instance2.hashCode():- "
+ instance2.hashCode()); //1829164700
}
}
Sorry for the bad title, but I found the code listed below on mkyoung.com and was wondering what this code does. Is this a way in Java to set some default value into a variable?
public class LanguageBean implements Serializable{
private static Map<String,Object> countries;
static{
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);
}
}
This bit declares a static field:
private static Map<String,Object> countries;
So it's accessible directly on the class, e.g. LanguageBean.countries (or just countries), but only from code within the class, because it's private.
This bit is a static initializer:
static{
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);
}
That runs when the class is loaded, before any instances are created, and does indeed add some entries to countries. If there are multiple static initializers, they're run in source code order. See Static Initializer Blocks in this tutorial.
FWIW, there are also per-instance versions of both of those. An instance field:
private int foo;
...and an instance initializer; they look a bit weird, because they're just blocks with nothing in front of the block:
{
this.foo = 42;
}
In context, and with a second instance member:
class Thing {
private int bar = 16; // An initializer on the declaration
private int foo;
// An instance initializer block
{
this.foo = 42; // Or just foo = 42;, but I prefer to be clear
}
}
So you can do the same sort of thing for instances.
Basically yes, it's formally called a static initializer. And per JLS-8.7 Static Initializers
A static initializer declared in a class is executed when the class is initialized (§12.4.2). Together with any field initializers for class variables (§8.3.2), static initializers may be used to initialize the class variables of the class.
Those are called Static Initialization Blocks.
A static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:
static {
// whatever code is needed for initialization goes here
}
A class can have any number of static initialization blocks, and they
can appear anywhere in the class body. The runtime system guarantees
that static initialization blocks are called in the order that they
appear in the source code.
There is an alternative to static blocks — you can write a private
static method:
class Whatever {
public static varType myVar = initializeClassVariable();
private static varType initializeClassVariable() {
// initialization code goes here
}
}
The advantage of private static methods is that they can be reused
later if you need to reinitialize the class variable.
They are called whenever the class is first initialized, and can be used to conveniently initialize fields.
The static variable countries which is declared as a Map is populated using a static initializer. There are two entries that are being added to the Map.
static{
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);
}
One effect of the
static initializer
is that it runs when the class is loaded and that the block is thread safe and therefore it is used in design patterns such as singletons etc. to alleviate the need for thread synchronization.
Please see this thread for details on that:
Are Java static initializers thread safe?
Think of it the same way you might think of an object's member fields. You might have something like this:
private final Map<String, Object> countries;
public ClassName(){
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);
}
This would initialize the member field each time a new ClassName() is declared to some "initial" state. The following:
static{
countries = new LinkedHashMap<String,Object>();
countries.put("English", Locale.ENGLISH); //label, value
countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);
}
...essentially does the same thing, except does it for static fields. Now when the class is loaded, this static block is called and initializes the static fields before they can be used so that they have some "initial" state. This is often used when you have something that will not change (for instance you may want to set up a map that makes lookup of certain things easy) or when you need to set something up that might throw an exception yet the thing you are trying to set up really should be static, such as:
private static KeyPairGenerator KPG;
static {
try {
KPG = KeyPairGenerator.getInstance("RSA");
KPG.initialize(2048);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.err.println("Couldn't get a Key Pair Generator...exiting");
System.exit(1);
}
}
In the above case, I only need a single KeyPairGenerator for all of my classes (assuming I'm always going to use RSA encryption with a key size of 2048). With this single KeyPairGenerator I can generate multiple public private key pairs. However, creating the KeyPairGenerator throws a NoSuchAlgorithm exception (which cannot happen since Java is required to support RSA with a key length of 2048). So I can still get my static KeyPairGenerator by using this static initializer.
It is used to create variable and initialize it during class loading (that's when static{} block executes).
As Java Language Specification States:
Static initializers (§8.7) are blocks of executable code that may be
used to help initialize a class.
And it is indeed commonly used in small tutorial programs to initialize values.
On the other hand they also have usage in "bigger" programs. You can also use it register classes in Factory object. In this case each concrete product registers itself in the factory. By doing this you don't have to modify factory class when new concrete product is added.
class OneProduct extends Product
{
...
static
{
ProductFactory.instance().registerProduct("ID1", new OneProduct());
}
public OneProduct createProduct()
{
return new OneProduct();
}
...
}
Seems like a very basic query but I was pondering how the static method main() below is able to execute a non static method(the constructor obviously) from it using the new keyword. Though I understand that new brings onto the table a few other things as well but how should I convince myself that this isn't an exception to the rule that static and non static methods can't using non static and static context respectively?
Below is the sample code:
public class ConstructorTest {
ConstructorTest(String str)
{
System.out.println("Constructor Printing "+str);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ConstructorTest cnst=new ConstructorTest("here");
}
}
The above code actually prints --> Constructor Printing here
or in other words executing the body of a Non static method from a Static method?
Any plausible explanations are welcome.
The Java Tutorial states that
[...] Constructors are not members.
Therefore, there is no problem in calling them, since they are not bound to instances of your class. This would not make sense - hence, you cannot do the following:
Thing thing = new Thing();
Thing anotherThing = thing.Thing();
A constructor is not a method, so you cannot apply "method logic" to them.
In case you want to know more, the whole instantiation process is very well documented in the JLS. See 12.5. Creation of New Class Instances.
Actually constructor is compiled into the static method, this is how JVM internally creates instances of classes.
You are executing non-static code, but you are not doing it in a static context.
for instance:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
do();
}
}
This can not work, since do is an instance method, which might run code that is specific to the instance. So, how would the VM know which instance to use, or what value x should have?
Now, to first use a constructor, which is possible from any context:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
C1 t = new C1();
t.do();
}
}
Here, even though you are calling the method from within a static method, you are using it through an instance, so not in a static context.
ConstructorTest is not a method.
its an constructor,and you can use the constructor for initialize class property.
you can also initialize the static variable from the constructor like that :-
public class XYZ
{
static int i=0;
public XYZ() {
i=1;//not an compile time error
}
public static void doSome(){}
public static void main(String[] args) {
}
}
On a formal language level you should read the line
ConstructorTest cnst = new ConstructorTest("here")
as a class instance creation expression. As a matter of fact, this is not a call to a constructor or any other method.
The instance creation does many steps, like allocating memory for the new object, initializing the fields, calling constructors and initializer blocks. See JLS §12.5 for a detailed step-by-step description. Thus being said, the constructor invocation is only a part of the instance creation.
Additionally, you might see constructors as being static parts of the class. In fact, constructor declaration are not members (see JLS §8.8) and thus they are not overridable (as static methods also). Beware: This is only half true. When being inside the constructor you already have the instance created, and you are able to call other instance methods and/or access instance fields.
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?
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.
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();
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
To me it's safe.
bundle is initialized right after GUIBuilder is loaded and therfore before getString is called for the first time.