These blocks are similar to the static initialization blocks with the only difference being the absence of the 'static' keyword. The Java compiler copies all the initializer blocks in the same order as they are in the source code in every constructor before any executable statement in that constructor.
public class InitializationWithInitializerBlock{
public static int staticIntField = 100;
private boolean instanceBoolField;
{
boolean y;
y = true; //or, y =
instanceBoolField = y;
}
}
So if you see all your constructors having same code-segment at the top then you will probably be better off keeping that in an initializer block as anyway the compiler would copy the block in every constructor at the top. This way you can at least make the code more readable, maintainable (as the common code will only be at one place), and if the size of common code is significant and if you have multiple constructors then using initializer block you can also reduce the size of your source code.
public class InitializerBlocks {
public static void main(String[] args) {
new InitializerBlocks();
}
//Constructor - 1
public InitializerBlocks(){
System.out.println("3");
}
//Initializer Block - 1
{
System.out.println("1");
}
//Initializer Block - 2
{
System.out.println("2");
}
}
Output
1
2
3
(Of course the above code is not making a good use of initializer blocks as they not initializing anything what they are actually meant to. The purpose here is just to show how a Java compiler places all the initializer blocks at the top in every constructor in the same order as they appear in the code.)
Alternative to Initializer Blocks in Java
You can use an instance method to initialize an instance field - in most of the cases you would like to make this instance method as 'final' as there will hardly be any need for the subclasses to override such a method (evidently, a non-final instance method would also do the job). Similarly if you need to call the method only from within the same class, you would probably make it 'private'.
public class InitializationWithPrivateInstanceMethod{
public static int staticIntField = 100;
private boolean instanceBoolField = privInstanceMeth();
private final boolean privInstanceMeth() {
boolean y;
//computing the value of y
y =
return y;
}
}
The advantage of using an instance method over an initializer block is that it gives you flexibility of re-initializing those instance fields by calling the corresponding final instance method(s) in some setter or in some other method. Another interesting scenario where you can't use an initializer block and you would probably need an instance method to do it for you: Suppose you have a need of using the code of initializer block in any of your sub-classes and suppose all your constructors have extra code as well in addition to the initializer block code which would be added to them on the top during compilation. Now in such a situation, if you need to set only those fields which are set in the initializer block then you can't do that directly in your subclass as the most you can do here is to call a super class constructor (that too would normally re-set all the instance fields) ... right? Having a final instance method would solve your problem here. Choosing a suitable access specifier will again follow the same rules what has been discussed in article mentioned in above paragraph. In this case since the sub-classes require access to that method, so choosing 'protected' as the access specifier should be fine.

No comments:
Post a Comment