Showing posts with label initialization. Show all posts
Showing posts with label initialization. Show all posts

January 5, 2010

Class initialization in Java

"Static init blocks are executed at class loading time, instance init blocks run right after the call to super() in a constructor. When multiple init blocks of a single type occur in a class, they run in order, from the top down." -K. Sierra & B. Bates, SCJP Sun Certified Programmer for Java 6 Study Guide (Exam 310-065)

Class loading time is the same as initialization time, which is described right at the top of section 12.4 of the Java Language Specification.

What happens if more than one class contains static init blocks? Are static init blocks guaranteed to run? My question at Stack Overflow covers these questions.

What about multiple instances of a class? As expected, the static initialization blocks do NOT run again. Modifying main() from the link above to this:


System.out.println("START");
new Child();
System.out.println("MIDDLE");
new Child();
System.out.println("END");


produces this output:

START
static - grandparent
static - parent
static - child
instance - grandparent
constructor - grandparent
instance - parent
constructor - parent
instance - child
constructor - child
MIDDLE
instance - grandparent
constructor - grandparent
instance - parent
constructor - parent
instance - child
constructor - child
END

Initialization blocks in Java

Code:

public class LoadTest
{
public static void main(String[] args)
{
System.out.println("START");
new Child();
System.out.println("END");
}
}

class Parent extends Grandparent {
// Instance init block
{
System.out.println("instance - parent");
}

// Constructor
public Parent() {
System.out.println("constructor - parent");
}

// Static init block
static {
System.out.println("static - parent");
}
}

class Grandparent {
// Static init block
static {
System.out.println("static - grandparent");
}

// Instance init block
{
System.out.println("instance - grandparent");
}

// Constructor
public Grandparent() {
System.out.println("constructor - grandparent");
}
}

class Child extends Parent {
// Constructor
public Child() {
System.out.println("constructor - child");
}

// Static init block
static {
System.out.println("static - child");
}

// Instance init block
{
System.out.println("instance - child");
}
}


Output:
START
static - grandparent
static - parent
static - child
instance - grandparent
constructor - grandparent
instance - parent
constructor - parent
instance - child
constructor - child
END

Default initialization in Java

In Java, class variables get initialized to default values. This code...

public class Test {
private static String _string;
private static byte _byte;
private static short _short;
private static int _int;
private static long _long;
private static float _float;
private static double _double;
private static boolean _boolean;
private static char _char;

public static void main(String[] args) {
System.out.println("str " + _string);
System.out.println("byt " + _byte);
System.out.println("sht " + _short);
System.out.println("int " + _int);
System.out.println("lng " + _long);
System.out.println("flt " + _float);
System.out.println("dbl " + _double);
System.out.println("bln " + _boolean);
System.out.println("chr " + _char);
}
}


...produces this output...

str null
byt 0
sht 0
int 0
lng 0
flt 0.0
dbl 0.0
bln false
chr [the non-printable character U+0000]

Unlike class variables, method-local variables are NOT automatically initialized. This code will produce a compile-time error ("the local variable anotherInt may not have been initialized"):

int anotherInt;
System.out.println(anotherInt);


On the other hand, the compiler won't catch non-initialized class objects; this code, after the earlier snippet, compiles just fine but will cause a NullPointerException at runtime:

if ("impossible".equals(_string)) {
int x = 5;
}