Initializers, Static Import, Access Modifiers

Initializers can be used to set initial values for fields in objects and classes. There are three different types of initializers:

  • field initializer expressions
  • static initializer blocks
  • instance initializer blocks (init)

Field Initializer Expressions

When an object is created using the new operator, instance initializer expressions are executed in the order in which the instance fields are declared in the class.


public class SomeInitializers {

int length = 10; // (1) Non-Static
 // double area = length * width; // (2) Not Ok. Illegal forward reference.
 double area = length * this.width; // (3) Ok, but width has default value 0.
 int width = 10; // (4)
 int sqSide = height = 20; // (5) OK. Legal forward reference.
 int height; // (6)
 int noOfDays = 7 * NO_OF_WEEKS;// (7) Nonstatic - OK- Legal forward as static varialbe will initialize first
 static int NO_OF_WEEKS = 52; // (8) Static
 //static int x=this.y; //(9) Not ok, illegal forward reference for static variables
 int y =10;
}

An initializer expression for a static field cannot refer to nonstatic members by their simple names. The keywords this and super cannot occur in a static initializer expression. Since a class is always initialized before it can be instantiated, an instance initializer expression can always refer to any static member of a class, regardless of the member declaration order. Java requires that the declaration of a field must occur before its usage in any initializer expression if the field is used on the right hand side of an assignment in the initializer expression. There is one caveat to the declaration-before-reading rule: it does not apply if the initializer expression defines an anonymous class, as the usage then occurs in a different class which has its own accessibility rules in the enclosing context. The forward reference at (5) is legal. The usage of the field height in the initializer expression at (5) occurs on the left hand side of the assignment. The initializer expression at (5) is evaluated as (sqSide = (height =20)). Every object of the class SomeInitializers will have the field height set to the value 20.

Lets take a look into another example:


package mynotes.shortConcepts;

public class BuggyInitializer {

 public int length=10;
 public int area=getArea();//BUG
 public int breath=5;

 public int getArea(){
 System.out.println("length::"+this.length);
 System.out.println("breath::"+this.breath);
 return this.length*this.breath;
 }

public static void main(String[] args) {
 BuggyInitializer aBuggyInitializer=new BuggyInitializer();
 System.out.println("After Object creation");
 System.out.println("area::"+aBuggyInitializer.area);
 System.out.println("length::"+aBuggyInitializer.length);
 System.out.println("breath::"+aBuggyInitializer.breath);

}
}

Output:


length::10
breath::0
After Object creation
area::0
length::10
breath::5

The call at  to the method getArea() is expected to return the area. However, the field breath will not have been explicitly initialized; therefore, its default value 0 will be used , which will return an incorrect value.

Initializer expressions in named classes and interfaces must not result in any uncaught checked exception. If any checked exception is thrown during execution of an initializer expression, it must be caught and handled by code called from the initializer expression. This restriction does not apply to instance initializer expressions in anonymous classes.

Static Block

A block defined using the keyword static. Executed only once when the class is loaded. Although such blocks can include arbitrary code, they are primarily used for initializing static fields. If a class relies on native method implementations, a static initializer can be used to load any external libraries that the class needs.


package mynotes.shortConcepts;

public class StaticBlocksEx {

static int[] values = new int[5];
 static {
 System.out.println("Running initialization block.");
 for (int i = 0; i < values.length; i++) {
 values[i] = (int) (100.0 * Math.random());
 }
 }

void listValues() {
 for (int value : values) {
 System.out.println(value);
 }
 }

public static void main(String[] args) {
 StaticBlocksEx example = new StaticBlocksEx();
 System.out.println("First object:");
 example.listValues();
 example = new StaticBlocksEx();
 System.out.println("Second object:");
 example.listValues();
 }

}

Output:


Running initialization block.
First object:
12
6
1
25
27
Second object:
12
6
1
25
27

Notice that the static block ran only once even though you created 2 objects.

When making forward references using simple names, code in a static initializer block is also subject to the declaration-before-reading rule discussed in the previous subsection. Exception handling in static initializer blocks is no different from that in static initializer expressions: uncaught checked exceptions cannot be thrown. A static initializer block cannot be called directly, therefore, any checked exceptions must be caught and handled in the body of the static initializer block.

INIT Block

Init block in always executed before constructor. It can be placed anywhere. If there are more than one init block then it will be executed sequentially. The need of it is that we may write a common code in the init block to reduce redundancy. Executed for each object that is created.Can initialize instance variables in a class.


package mynotes.shortConcepts;

public class InitBlockEx {

 static int[] values = new int[5];
 {
 System.out.println("Running initialization block.");
 for (int i = 0; i < values.length; i++) {
 values[i] = (int) (100.0 * Math.random());
 }
 }

void listValues() {
 for (int value : values) {
 System.out.println(value);
 }
 }

public static void main(String[] args) {
 InitBlockEx example = new InitBlockEx();
 System.out.println("First object:");
 example.listValues();
 example = new InitBlockEx();
 System.out.println("Second object:");
 example.listValues();
 }

}

Output:


Running initialization block.
First object:
55
76
57
96
20
Running initialization block.
Second object:
20
12
15
46
81

Notice init block ran every time an object is created.

Exception handling in instance initializer blocks differs from that in static initializer blocks in the following aspect: the execution of an instance initializer block can result in an uncaught checked exception, provided the exception is declared in the throws clause of every constructor in the class. Static initializer blocks cannot allow this, since no constructors are involved in class initialization. Instance initializer blocks in anonymous classes have even greater freedom: they can throw any exception.

Static Import

If you don’t use import statement, you can still use the classes of that package. But you should invoke it with package reference whereever you use.
That is like, package.ClassA obj = new package.ClassA(); – looks very ugly isn’t it?

Consider the java example: double r = Math.cos(Math.PI * theta);
How about writing the same java code like: double r = cos(PI * theta); – looks more readable right?
This is where static import in java comes to help you.
import static java.lang.Math.PI;
import static java.lang.Math.cos;

Please don’t use this feature, because over a period you may not understand which static method or static attribute belongs to which class inside the java program. The program may become unreadable. Use whenever you require frequent access to static members from one or two java classes.

Java Access Modifiers

Java provides a number of access modifiers to set access levels for classes, variables, methods and constructors. The four access levels are:

  • Visible to the package. the default. No modifiers are needed.
  • Visible to the class only (private).
  • Visible to the world (public).
  • Visible to the package and all subclasses (protected).

Grab all the code from my GitHub repository.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: