initialisation : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

initialisation
Introduction Quirks
Three Types Of Variable static final init Catch-22
Constant Variables Learning More
Summary of Order of Initialisation Links
Order of Initialisation

Introduction

Java automatically initialises all non-local variables with a default value, i.e. 0 or null, even chars. However, Java does not automatically initialise local variables, though it will initialise any arrays or objects newly created to be stored in local variables. The Java compiler is clever. If you forget to initialise when it is required, it will tell you at compile time. You never need to worry about inadvertently accessing uninitialised variables. Java always protects you from your folly. When you create an array of objects, Java automatically initialises all the slots to null, for both singly and doubly dimensioned arrays e.g. String [ ] or String [ ] [ ]. It does not create a new object for each slot.

Three Types Of Variable

There are three kinds of variable, local, instance (one value per object) and static (one per class). When you first use a class, its class variables are initialised. When you first use a new SomeConstructor, the object’s instance variables are initialised. There is no automatic initialisation for local variables. Usually you initialise them inline. Here is the order in which the six types of initialisation are applied. The types of initialisation near the top of the table are applied first.

Various Ways To Initialise the Three Kinds of variables
Type of Initialisation Local Instance Static Notes
automatic null or zero No code needed. char = 0, not ' '; reference = null, int = 0; At the hardware level, all bytes in new object or class are first bulk cleared to 0 bytes, which initialises everything appropriately. Strings are represented as a null reference, not as an array of embedded blank bytes, so they too work.
inline known finals
e.g. final int MAX_WEIGHT = 1000;
If the compiler can figure out the value of the expression at compile time, it gets done first ahead of the other inline initialisations. If it can’t, then it is treated as an ordinary inline initialisation, even though it is final.
inline
e.g. int a = 1;
Interleaved in textual order with static {} or instance {}.
static init block
e.g. static {a = 1;}
* Interleaved in textual order with inline initialisations. There is a separate static init for a nested class that is not run until a nested class is first instantiated.
init block
e.g. {a = 1;}
* Interleaved in textual order with inline initialisations.
constructor
e.g. a = 1;
constructor to see how constructors are chained to do a series of initialisations
assignment in a method
e.g. a = 1;
procedural code, not really initialisation.

local variables initialised in an init block or static init block must be declared in that block and have scope confined to that block.

Constant Variables

The JLS uses the term constant variable for a final whose value is known at compile time, even if indirectly. This is an oxymoron. Perhaps we could use the terms named constant, primal or cknown for compile-time-known instead.

Java just initialises in textual order.

In tidying, I sometimes screw things up so there is a reference before a definition. Java is not like a spreadsheet cleverly sorting out natural initialization order.

One brute force way to avoid declaration ordering problems is to put all your interdependent initialisation values in a static init block and put that block after all your static declarations.

Summary of Order of Initialisation

  1. static/instance final constants computed at compile time converted to inline literals
  2. zero all class variables
  3. super classes of this class are loaded
  4. static = declaration initialisation
  5. static {init} code
  6. then when we instantiate a new object
  7. zero all instance variables
  8. instance = declaration initialisation
  9. instance {init} code
  10. constructor of Object
  11. constructor of parent
  12. constructor of this object

Order of Initialisation

After the zero initialisations, the class variable initializers and static initializers of the class, or the field initializers of the interface, are executed in textual order, as though they were a single block, except that final class variables and fields of interfaces whose values are compile-time constants are initialized first. In other words static final constants known at compile time are logically done first. They are done very first, at compile time and by the time you load a class they are effectively literals. There are no actual static final variable slots that can be initialised.

If you decompile you code, you will see a generated method called <clinit> that handles the static initialisation.

Beware of depending on inline initialisations of member or class variables being done in the order the variables are listed because various beautifier tools such asr Eclipse or Intellij rearranger may reorder them. When the value of one variable depends on another, put the dependent initialisations in an init or static init block, where you have explicit control of the ordering, rather than using initialisation assignment statements. The compiler is not smart like a spreadsheet to figure out the dependencies and calculate them in natural order. It just starts and the top and works down doing the assignment initialisations and block initialisations in strict top down order.

The constructor must call the constructor of the superclass as the very first thing it does. If you leave out this code, the compiler inserts it for you. This means when you invoke a constructor, first the base fields are initialised, then the subclass. You are effectively invoking a daisy chain of constructors of the ancestor classes when you invoke a constructor.

Quirks

There are three quirky consequences of the way Java does initialisation:

  1. You can safely do forward references to compile time constants in your initialisation code.
  2. You can define the value for a static final in a static init block that appears before the declaration.
  3. You many not do a forward reference in your initialisation code to a constant whose value is not known at compile time.
  4. You may not use values passed to constructors in the other initialisation code, because that code has already finished executing by time the constructor starts. You may only use passed values in code in the constructor that initialises fields.

static final init Catch-22

There is a Catch-22 if you invoke code that could trigger exceptions in your static constant  The Catch-22 is if you don’t initialise in the catch block, the compiler complains the var WEBSITEURL might never be initialised, but it you do initialise in the catch block, it complains you may be initialising twice. Further, you can’t simply wrap the static final declaration in a try block.

Here is a way to bypass the problem:

A variant would be to write a method to provide the initial value that handled the exception to disguise the ugliness.

Learning More


This page is posted
on the web at:

http://mindprod.com/jgloss/initialisation.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\initialisation.html
Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

IP:[65.110.21.43]
Your face IP:[54.211.203.45]
You are visitor number