Instantiation

From Suhrid.net Wiki

Jump to: navigation, search

Contents

Constructors

  • Every class - including Abstract classes - MUST have a constructor.
  • Constructor chaining is built in. Every class constructor will call its default superclass constructor using super().
  • Every constructor as its first statement has a call to this() or super().
  • Compiler will only automatically insert call to no-arg super() or this().
  • CANNOT call an instance method or access instance variables till the super constructor has run.
  • Only Static variables can be accessed as a call to super() or this().

Field Initializers

  • Initialization of fields can be done through field declaration statements.
  • Declaration of field must occur before its usage in any initializer if it is used on the RHS of an assignment. This will always result in a compiler error. Example:
public class Init4 {
 
	int length = 10;
 
	int area = length * width; //Illegal since width is a forward reference being used on the RHS.
 
	int width = 20;
 
}
  • Initializer expression must not result in an uncaught checked exception. Compiler will throw an error.
public class Init4 {
 
	int length = 10;
 
        int width = 20;
 
	int area = getArea(); //Compiler error - uncaught exception.
 
        private int getArea() throws Exception {
            return length * width;
        }
}

Final Fields Initialization

  • Final fields don't get default values, they have to be explicitly initialized.
  • A final variable can only be initialized once, either via an initializer or an assignment statement. If a final instance variable is not assigned a value - there will be a compiler error !
  • If not initialized at the point of declaration: this is called a 'blank final' variable.
  • A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared or an instance initializer block can be used.
  • Similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared.
  • Instance Init Blocks or constructors cannot assign values to final static variables - this will be a compiler error. Why ? An object of the class might never be created and the static final variable will be unintialized.
  • A final field has to be initialized in every constructor OR the compiler will complain.
public class InitFinals {
 
	final int inst_i;
	static final int stat_i;
 
	InitFinals() {
		inst_i = 2;
	}
 
	InitFinals(String str) {
		inst_i = 3;
	}
 
	static {
		stat_i = 20;
	}
 
	public static void main(String[] args) {
 
	}
 
}
  • Alternatively the final field can be assigned in an intializer block, however if the field is also being assigned in the constructor then the compiler complains.
  • Why ? Because the initializer runs before rest of the constructor body, so it will amount to reassigning the final variable which is not allowed.
public class InitFinals {
 
	final int inst_i;
	static final int stat_i;
 
	InitFinals() {
		inst_i = 2; //COMPILER ERROR HERE
	}
 
	{
		inst_i = 3;
	}
 
	static {
		stat_i = 20;
	}
 
	public static void main(String[] args) {
 
	}
 
}

Initialization Blocks

  • A static initialization block runs when the class is first loaded.(Runs only once)
  • An instance init block runs every time a new instance is created.
  • An instance init block runs right after the call to super() in a constructor (ie. after all the super-constructors have run).
  • In case of multiple init blocks (either instance and static) they run in the order in which they are defined.
  • An interface CANNOT have any intialization blocks. Only initializer expressions for its static variables.
  • Exceptions in init blocks can be handled using try-catch mechanism.
  • A java.lang.ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer block or the initializer for a static variable.
  • An instance-init block can result in an uncaught exception - provided that the exception is declared in the throws clause of every constructor.
  • In a static - init block this is NOT possible - since there is no constructor invocation to handle the exception. So no uncaught checked exceptions are possible for static initializers.
  • Example:
public class Init5 {
 
	private int id;
 
	private static int count = 10;
 
	static {
		if(count < 20) {
			throw new FileNotFoundException(); //Error
		}
	}
 
	{
		    if(id > 0) {
		    	throw new InterruptedException();   //Uncaught checked exception allowed, because constructor declares it.
		    }
	}
 
	Init5(int id) throws InterruptedException {
		this.id = id;
	}
 
	public static void main(String[] args) {
 
		try {
			Init5 i0 = new Init5(0);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
 
	}
 
}

Complete Initialization Order

  • Class is initialized only when it is referenced.
  • Instance level data is initialized only when an object is constructed.
  1. Class level initialization takes place before any instance of the class can be created or a static method of the class is invoked.
    1. Superclass is initialized before its sub class
    2. All static initializer expressions and static initializer blocks are executed in the order in which they appear. i.e. all static parts of the class hierarchy (starting top-down) are initialized before instance initialization begins.
  2. Next, all instance fields are initialized to their default values (irrespective of whether they get non-default initial values later or not)
  3. Constructor is invoked which starts constructor chaining.
  4. Once all super constructors finish executing, Initialization of the instance fields happens by either initializer expressions or initializer blocks in the order in which they are specified.
  5. Constructor resumes executing.
Personal tools