As far as I understood the "static initialization block" is used to set values of static field if it cannot be done in one line.
But I do not understand why we need a special block for that. For example we declare a field as static (without a value assignment). And then write several lines of the code which generate and assign a value to the above declared static field.
Why do we need this lines in a special block like: static {...}
?
If your static variables need to be set at runtime then a
static {...}
block is very helpful.For example, if you need to set the static member to a value which is stored in a config file or database.
Also useful when you want to add values to a static
Map
member as you can't add these values in the initial member declaration.If they weren't in a static initialization block, where would they be? How would you declare a variable which was only meant to be local for the purposes of initialization, and distinguish it from a field? For example, how would you want to write:
If
first
andsecond
weren't in a block, they'd look like fields. If they were in a block withoutstatic
in front of it, that would count as an instance initialization block instead of a static initialization block, so it would be executed once per constructed instance rather than once in total.Now in this particular case, you could use a static method instead:
... but that doesn't work when there are multiple variables you wish to assign within the same block, or none (e.g. if you just want to log something - or maybe initialize a native library).
It is a common misconception to think that a static block has only access to static fields. For this I would like to show below piece of code that I quite often use in real-life projects (copied partially from another answer in a slightly different context):
Here the initializer is used to maintain an index (
ALIAS_MAP
), to map a set of aliases back to the original enum type. It is intended as an extension to the built-in valueOf method provided by theEnum
itself.As you can see, the static initializer accesses even the
private
fieldaliases
. It is important to understand that thestatic
block already has access to theEnum
value instances (e.g.ENGLISH
). This is because the order of initialization and execution in the case ofEnum
types, just as if thestatic private
fields have been initialized with instances before thestatic
blocks have been called:Enum
constants which are implicit static fields. This requires the Enum constructor and instance blocks, and instance initialization to occur first as well.static
block and initialization of static fields in the order of occurrence.This out-of-order initialization (constructor before
static
block) is important to note. It also happens when we initialize static fields with the instances similarly to a Singleton (simplifications made):What we see is the following output:
Clear is that the static initialization actually can happen before the constructor, and even after:
Simply accessing Foo in the main method, causes the class to be loaded and the static initialization to start. But as part of the Static initialization we again call the constructors for the static fields, after which it resumes static initialization, and completes the constructor called from within the main method. Rather complex situation for which I hope that in normal coding we would not have to deal with.
For more info on this see the book "Effective Java".
I would say
static block
is just syntactic sugar. There is nothing you could do withstatic
block and not with anything else.To re-use some examples posted here.
This piece of code could be re-written without using
static
initialiser.Method #1: With
static
Method #2: Without
static
You can execute bits of code once for a class before an object is constructed in the static blocks.
E.g.
The non-static block:
Gets called every time an instance of the class is constructed. The static block only gets called once, when the class itself is initialized, no matter how many objects of that type you create.
Example:
This prints: