Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of Initializers vs Constructors in Java

So I've been brushing up on my Java skills as of late and have found a few bits of functionality that I didn't know about previously. Static and Instance Initializers are two such techniques.

My question is when would one use an initializer instead of including the code in a constructor? I've thought of a couple obvious possibilities:

  • static/instance initializers can be used to set the value of "final" static/instance variables whereas a constructor cannot

  • static initializers can be used to set the value of any static variables in a class, which should be more efficient than having an "if (someStaticVar == null) // do stuff" block of code at the start of each constructor

Both of these cases assume that the code required to set these variables is more complex than simply "var = value", as otherwise there wouldn't seem to be any reason to use an initializer instead of simply setting the value when declaring the variable.

However, while these aren't trivial gains (especially the ability to set a final variable), it does seem that there are a rather limited number of situations in which an initializer should be used.

One can certainly use an initializer for a lot of what is done in a constructor, but I don't really see the reason to do so. Even if all constructors for a class share a large amount of code, the use of a private initialize() function seems to make more sense to me than using an initializer because it doesn't lock you into having that code run when writing a new constructor.

Am I missing something? Are there a number of other situations in which an initializer should be used? Or is it really just a rather limited tool to be used in very specific situations?

like image 683
Inertiatic Avatar asked Apr 29 '09 22:04

Inertiatic


People also ask

Which will execute first static block or constructor?

Order of execution When you have all the three in one class, the static blocks are executed first, followed by constructors and then the instance methods.

Is constructor same as initializer?

A class object with a constructor must be explicitly initialized or have a default constructor. Except for aggregate initialization, explicit initialization using a constructor is the only way to initialize non-static constant and reference class members.

What is difference between static block and constructor?

Constructors run EVERY time a new instance of the class is created. And, of course, the static blocks (if they exist) are run first. Constructors will run as they are executed in your code. That is when you create new instances of the class.

Why do we need initializer in Java?

In order to perform any operations while assigning values to an instance data member, an initializer block is used. In simpler terms, the initializer block is used to declare/initialize the common part of various constructors of a class. It runs every time whenever the object is created.


2 Answers

Static initializers are useful as cletus mentioned and I use them in the same manner. If you have a static variable that is to be initialized when the class is loaded, then a static initializer is the way to go, especially as it allows you to do a complex initialization and still have the static variable be final. This is a big win.

I find "if (someStaticVar == null) // do stuff" to be messy and error prone. If it is initialized statically and declared final, then you avoid the possibility of it being null.

However, I'm confused when you say:

static/instance initializers can be used to set the value of "final" static/instance variables whereas a constructor cannot

I assume you are saying both:

  • static initializers can be used to set the value of "final" static variables whereas a constructor cannot
  • instance initializers can be used to set the value of "final" instance variables whereas a constructor cannot

and you are correct on the first point, wrong on the second. You can, for example, do this:

class MyClass {     private final int counter;     public MyClass(final int counter) {         this.counter = counter;     } } 

Also, when a lot of code is shared between constructors, one of the best ways to handle this is to chain constructors, providing the default values. This makes is pretty clear what is being done:

class MyClass {     private final int counter;     public MyClass() {         this(0);     }     public MyClass(final int counter) {         this.counter = counter;     } } 
like image 147
Eddie Avatar answered Sep 28 '22 18:09

Eddie


Anonymous inner classes can't have a constructor (as they're anonymous), so they're a pretty natural fit for instance initializers.

like image 29
Alex Martelli Avatar answered Sep 28 '22 18:09

Alex Martelli