I found that in Java, there is a feature called static block
, which includes code that is executed when a class is first loaded (I don't understand what 'loaded' means, does it mean initialized?). Is there any reason to do the initialization bit inside a static block and not in the constructor? I mean, even the constructor does the same thing, do all the necessary stuff when a class is first initialized. is there anything that the static block accomplishes which a constructor can't?

- 21,918
- 9
- 70
- 118

- 7,913
- 28
- 108
- 196
-
3Called once when the class is loaded by the class loader. Not each time the class is instantiated. – Wolfgang Kuehn Dec 21 '12 at 18:00
-
2Please, take a look at the following chapters of the Official Java Tutorial (from Oracle): [Understanding Instance and Class Members](http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html) and [Initializing Fields](http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html). Come back if you still have any doubts. – Anthony Accioly Dec 21 '12 at 18:02
-
Just a non-sequitur question, if a class happens to have both `main` and a constructor, which one is invoked earlier when an instance of the class is created? – SexyBeast Dec 21 '12 at 18:10
-
1Initialization code (Classloading time) -> Main (Application entry point) -> Constructors: Here's a [working example](http://ideone.com/QWB43H) to further illustrate the point. – Anthony Accioly Dec 21 '12 at 18:27
-
For the example you provided, why isn't it falling into an infinite recursion? I mean, first time the class `Main` is invoked, the static block is executed all right. But since the `Main` class is itself again invoked inside the `main` method, they will create new instances of `Main`. While being instantiated, the static block won't execute, but their `main` methods will execute, creating two further instances, and so on. – SexyBeast Dec 21 '12 at 18:49
-
@Cupidvogel - A class is loaded and initialized (including running any `static` blocks and static initializers) before any instances are created. (This might be triggered by an attempt to create an instance, but it's a separate process from instance creation.) When you later create instances of that class, the static blocks are not executed again (the same goes for static initializers). Thus there will be no recursion for a class with a `static` block and a `main` method. – Ted Hopp Dec 21 '12 at 19:39
-
1@Cupidvogel The `main` method is not run every time an instance of a class is created. It is only run when either explicitly invoked (just like any other static method) or when the JVM begins the application. – Thorn G Dec 21 '12 at 19:42
-
Just creating an instance of a class with a main method will not invoke it. Remember that the main method is a `static` entry point that will be executed implicity by the JVM **once**. While you certainly can invoke the `main` method explicitly and even in a recursively fashion, it definitively sounds like a bad idea :). – Anthony Accioly Dec 21 '12 at 19:45
-
Looks like a duplicate of http://stackoverflow.com/questions/2420389/static-initialization-blocks – Aaron Kurtzhals Dec 21 '12 at 19:56
-
Can anybody please explain what is meant by 'loaded'? How is it different from 'initialized'? – SexyBeast Dec 21 '12 at 20:05
-
It's all spelled out in gory detail in [Chapter 5 of the Java Virtual Machine Specification](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html). Roughly speaking, "loading" is reading the byte codes into memory while "initialized" means that the initialization code for the class is executed. – Ted Hopp Dec 21 '12 at 20:15
-
I was going through the Chapter 12 at http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2, and couldn't decipher head or tail of it. Can you point me to a better resource that discusses it just as much at length, but much more lucidly, and if possible, with a number of examples? – SexyBeast Dec 21 '12 at 20:19
-
Google is your friend here. This is a complicated subject, so don't expect anything that's real easy to digest. [This introduction to the subject](http://www.artima.com/insidejvm/ed2/lifetype.html) might be what you are looking for. – Ted Hopp Dec 23 '12 at 02:39
-
Yeah, it looks really complicated. Gonna take me quite some effort and time to digest it.. – SexyBeast Dec 23 '12 at 07:42
12 Answers
I first want to highlight one thing thing from your question:
the constructor does the same thing, do all the necessary stuff when a class is first initialized
This is incorrect. A constructor does all the initialization necessary when an instance of a class is created. No constructors execute when the class itself is first loaded into memory and initialized (unless an instance of the class happens to be created as part of the class initialization). This confusion (between initializing a class and initializing instances of the class) is probably why you are questioning the utility of static
blocks.
If a class has static members that require complex initialization, a static
block is the tool to use. Suppose you need a static map of some kind (the purpose is irrelevant here). You can declare it in-line like this:
public static final Map<String, String> initials = new HashMap<String, String>();
However, if you want to populate it once, you can't do that with an in-line declaration. For that, you need a static
block:
public static final Map<String, String> initials = new HashMap<String, String>();
static {
initials.put("AEN", "Alfred E. Newman");
// etc.
}
If you wanted to be even more protective, you can do this:
public static final Map<String, String> initials;
static {
Map<String, String> map = new HashMap<String, String>()
map.put("AEN", "Alfred E. Newman");
// etc.
initials = Collections.unmodifiableMap(map);
}
Note that you cannot initialize initials
in-line as an unmodifiable map because then you couldn't populate it! You also cannot do this in a constructor because simply calling one of the modifying methods (put
, etc.) will generate an exception.
To be fair, this is not a complete answer to your question. The static
block could still be eliminated by using a private static function:
public static final Map<String, String> initials = makeInitials();
private static Map<String, String> makeInitials() {
Map<String, String> map = new HashMap<String, String>()
map.put("AEN", "Alfred E. Newman");
// etc.
return Collections.unmodifiableMap(map);
}
Note, though, that this is not replacing a static
block with code in a constructor as you proposed! Also, this won't work if you need to initialize several static
fields in an interrelated way.
A case where a static
block would be awkward to replace would be a "coordinator" class that needs to initialize several other classes exactly once, especially awkward if it involves dependency injection.
public class Coordinator {
static {
WorkerClass1.init();
WorkerClass2.init(WorkerClass1.someInitializedValue);
// etc.
}
}
Particularly if you don't want to hard-wire any dependence into WorkerClass2
on WorkerClass1
, some sort of coordinator code like this is needed. This kind of stuff most definitely does not belong in a constructor.
Note that there is also something called an instance initializer block. It is an anonymous block of code that is run when each instance is created. (The syntax is just like a static
block, but without the static
keyword.) It is particularly useful for anonymous classes, because they cannot have named constructors. Here's a real-world example. Since (unfathomably) GZIPOutputStream
does not have a constructor or any api call with which you can specify a compression level, and the default compression level is none, you need to subclass GZIPOutputStream
to get any compression. You can always write an explicit subclass, but it can be more convenient to write an anonymous class:
OutputStream os = . . .;
OutputStream gzos = new GZIPOutputStream(os) {
{
// def is an inherited, protected field that does the actual compression
def = new Deflator(9, true); // maximum compression, no ZLIB header
}
};

- 232,168
- 48
- 399
- 521
-
1
-
@Cupidvogel What if the class has no constructors? `java.lang.Math` only contains static methods and is never instantiated for example. (Although `Math` contains a constructor, but curiously that constructor is there to make sure no instances are created.) – biziclop Dec 21 '12 at 18:10
-
2Another typical usage of static initialisers is the loading of a native library for classes that have native methods, like this: `static { System.loadLibrary ("foo"); }` – biziclop Dec 21 '12 at 18:11
-
2@Cupidvogel - Since the variable is declared both `static` and `final` (so that it cannot be changed), the language will not allow you to do it in the constructor. – Ted Hopp Dec 21 '12 at 18:13
-
What do you mean by **What if the class has no constructors?**? I want to know is there any particular case where a constructor can't do something the static block can do? – SexyBeast Dec 21 '12 at 18:14
-
1@Cupidvogel, do you understand the concept of a class and instantiating it? If you put that code in the constructor then every time you created a new instance the same entry would be added the map again. You want this behavior to happen once on the class level, not for every instance. – John Dec 21 '12 at 18:15
-
@Cupidvogel See Ted's comment: you can't initialise a `static final` field from a constructor. And that's a hard limit, your code will simply not compile. But you can easily have classes that have a single empty `private` constructor to prevent instantiation. Even if you put some code in it, it will never be called. (As it's `private`, no-one can see it.) – biziclop Dec 21 '12 at 18:17
-
1@Cupidvogel - I think what I posted is a case where a constructor can't do something the static block can do. (Note that this isn't a case where a constructor _should not_ be used; it's a case where a constructor **cannot** be used.) – Ted Hopp Dec 21 '12 at 18:19
-
Okay, I kind of got the point, but the example you provided is not correct I think, even if I add the same key to a hash 50 times, it has but only one key of that value.. – SexyBeast Dec 21 '12 at 18:19
-
@Cupidvogel - In the last case, since the map itself is unmodifiable (to protect it from changes in other code), you cannot add to it (even the same value) in a constructor. You will get a run-time exception if you try. – Ted Hopp Dec 21 '12 at 18:20
-
Another, slightly more subtle problem with setting static fields from instance methods (e.g. constructors) is multi-threading. While it is guaranteed that all the static initialisers will run and their results will be visible to all threads, there's no such guarantee for constructors setting static fields. – biziclop Dec 21 '12 at 18:21
-
Oh ho, by final does it mean that after initialization it can never be modified (the term `final` implies that, btw, so forgive me my dumbness)? – SexyBeast Dec 21 '12 at 18:24
-
@biziclop, hold that, I haven't yet learnt about multithreading, but when i do, i will get back to you on your comment... – SexyBeast Dec 21 '12 at 18:25
-
@Cupidvogel - A `final` variable must be "definitely assigned" a value **exactly** once. If there is no assignment, or (as far as the compiler can tell) a chance that the assignment will not be executed or will be executed more than once, then it will generate an error. The method `Collections.unmodifiableMap` has nothing to do with `final`; it takes any `Map` and turns it into another `Map` that will generate an exception at run time for any attempt to add, modify, or delete any entry in the map. When using both `final` and unmodifiable, a `static` block is indispensable. – Ted Hopp Dec 21 '12 at 18:34
Constructor is invoked while creating an instance of the class.
Static block is invoked when a classloader loads this class definition, so that we can initialize static members of this class. We should not be initializing static members from constructor as they are part of class definition not object

- 10,870
- 3
- 37
- 42
-
1
-
Each class needs to be loaded to jvm via a classloader, It can happen when a object of the type of that class is requested in code or a static variable is requested in code. For eg: int b= ClassA.staticMenber; staticMember is a static variable present in ClassA, which can be initilized in static block. – Subin Sebastian Dec 21 '12 at 18:05
-
So essentially you mean 'when a instance of that class is first created' by 'loaded', right? – SexyBeast Dec 21 '12 at 18:07
-
please see the edit. it can be when instance created, or a static reference made. – Subin Sebastian Dec 21 '12 at 18:08
-
1+1 for ***We should not be initializing static members from constructor as they are part of class definition not object*** – Aman Gupta Oct 28 '14 at 15:05
-
There are sometimes reasons to modify a `static` field in a constructor. This technique is used, for instance, to generate a unique id for each instance of a class: define, say, a `private static int nextID` field, initialized (statically) to 0, and then in the constructor assign `this.id = nextID++;`. – Ted Hopp Oct 16 '17 at 01:17
Static initializer will run if we initialize a class, this does not require that we instantiate a class. But the constructor is run only when we make an instance of the class.
For example:
class MyClass
{
static
{
System.out.println("I am static initializer");
}
MyClass()
{
System.out.println("I am constructor");
}
static void staticMethod()
{
System.out.println("I am static method");
}
}
If we run:
MyClass.staticMethod();
Output:
I am static initializer
I am static method
We never created an instance so the constructor is not called, but static initializer is called.
If we make an instance of a class, both static initilizer and the constructor run. No surprises.
MyClass x = new MyClass();
Output:
I am static initializer
I am constructor
Note that if we run:
MyClass x;
Output: (empty)
Declaring variable x
does not require MyClass
to be initialized, so static initializer does not run.

- 82,592
- 51
- 207
- 251
-
2You are misinterpreting what's going on. Static blocks _are_ run when the class is initialized. It's just that simply declaring a variable `MyClass x` does not require that the class be loaded or initialized. Java is smart enough to know that it can defer loading and initializing the class until something about it (other than it's name) is actually needed. (By the way, simply referencing a static field of the class will also cause the class to be initialized. You don't need to create an instance or call a method.) – Ted Hopp Dec 21 '12 at 19:42
-
@Ted Hopp I edited my answer to reflect your point, which basically the gist of my answer now. – Akavall Dec 21 '12 at 19:51
-
Much improved. However, I don't see how this addresses OP's question. – Ted Hopp Dec 21 '12 at 19:55
-
@Ted Hopp, the OP is basically asking about the difference between static initializer and constructor. OP's last question is "is there anything that the static block accomplishes which a constructor can't". My answer illustrates that static initializer is run when instance of of `MyClass` is not created, while constructor is not. This is something that static initializer can do, and constructor cannot do. – Akavall Dec 21 '12 at 20:04
The static initializer runs when the class is loaded even if you never create any objects of that type.
- Not all classes are meant to be instantiated. The constructor might never be called. It might even be private.
- You may wish to access static fields of the class before you run a constructor.
- The static initializer only runs once when the class is loaded. The constructor is called for each object of that type you instantiate.

- 811,555
- 193
- 1,581
- 1,452
You can't initialize static variables with a constructor -- or at least you probably shouldn't, and it won't be particularly useful.
Especially when you're trying to initialize static constants that require significant logic to generate, that really ought to happen in a static block, not a constructor.

- 191,574
- 25
- 345
- 413
-
I wasn't the downvoter but I suspect the problem was that technically you can initialise static variables in a constructor. – biziclop Dec 21 '12 at 18:07
-
I agree with you completely, it was just a theory about the reason of the downvote. – biziclop Dec 21 '12 at 18:15
They're two separate things. You use a constructor to initialize one instance of a class, the static initialization block initializes static members at the time that the class is loaded.

- 94,330
- 19
- 181
- 276
The static block is reqly useful when you do have to do some action even if no instances is still created. As example, for initializing a static variable with non static value.

- 1,375
- 2
- 12
- 28
static block does different thing than constructor . Basically there sre two different concepts.
static block initializes when class load into memory , it means when JVM read u'r byte code. Initialization can ne anything , it can be variable initialization or any thing else which should be shared by all objects of that class
whereas constructor initializes variable for that object only .

- 909
- 2
- 17
- 43
The static block is useful over constructors when you do have to do some action even if no instances is still created. As example, for initializing a static variable with non static value.

- 21
- 4
One way you can understand static block is; It acts as a constructor. however, the difference between the two is static block instantiates class or static variables while constructor is used to instantiate object variables
Consider the following class
public class Part{
String name;
static String producer;
public Part(String name){
this.name = name;
}
static {
producer = "Boeing";
}
}
objects created from this class will have producer set to Boeing but their name is different depending on the argument passed. for instance
Part engine = new Part("JetEngine");
Part Wheel = new Part("JetWheel");

- 4,126
- 1
- 35
- 30
Initializing static fields in the constructor is a big mistake. Yes, you can initialize static fields in the constructor. However, the static fields will reset their value every time an object is created.
public class StaticExample {
static int myStaticField;
public StaticExample(){
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will reset the static field
StaticExample obj2 = new StaticExample();
// this will print 10
System.out.println(StaticExample.myStaticField);
}
}
This is unexpected and unaccepted behavior for a static field. If you now change the initialization step from a constructor to a static block, you will get the correct values.
public class StaticExample {
static int myStaticField;
static {
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will NOT reset the static field
StaticExample obj2 = new StaticExample();
// this will print 90
System.out.println(StaticExample.myStaticField);
}
}

- 192
- 2
- 4