8.3.2 Initialization of Fields

8.3.2 Initialization of Fields

If a field declarator contains a variable initializer, then it has the semantics of an assignment (§15.25) to the declared variable, and:

  • If the declarator is for a class variable (that is, a static field), then the variable initializer is evaluated and the assignment performed exactly once, when the class is initialized (§12.4).
  • If the declarator is for an instance variable (that is, a field that is not static), then the variable initializer is evaluated and the assignment performed each time an instance of the class is created (§12.5).

The example:

class Point {
    int x = 1, y = 5;
}

class Test {
    public static void main(String[] args) {
        Point p = new Point();
        System.out.println(p.x + ", " + p.y);
    }
}

produces the output:

1, 5

because the assignments to x and y occur whenever a new Point is created.

Variable initializers are also used in local variable declaration statements (§14.3), where the initializer is evaluated and the assignment performed each time the local variable declaration statement is executed.

It is a compile-time error if the evaluation of a variable initializer for a field of a class (or interface) can complete abruptly with a checked exception (§11.2).

8.3.2.1 Initializers for Class Variables

A compile-time error occurs if an initialization expression for a class variable contains a use by a simple name of that class variable or of another class variable whose declaration occurs to its right (that is, textually later) in the same class. Thus:

class Test {
   static float f = j;                         // compile-time error: forward reference
   static int j = 1;
   static int k = k+1;                         // compile-time error: forward reference
}

causes two compile-time errors, because j is referred to in the initialization of f before j is declared and because the initialization of k refers to k itself.

If a reference by simple name to any instance variable occurs in an initialization expression for a class variable, then a compile-time error occurs.

If the keyword this(§15.7.2) or the keyword super (§15.10.2, §15.11) occurs in an initialization expression for a class variable, then a compile-time error occurs.

(One subtlety here is that, at run time, static variables that are final and that are initialized with compile-time constant values are initialized first. This also applies to such fields in interfaces (§9.3.1). These variables are "constants" that will never be observed to have their default initial values (§4.5.4), even by devious programs. See §12.4.2 and §13.4.8 for more discussion.)

8.3.2.2 Initializers for Instance Variables

A compile-time error occurs if an initialization expression for an instance variable contains a use by a simple name of that instance variable or of another instance variable whose declaration occurs to its right (that is, textually later) in the same class. Thus:

class Test {
    float f = j;
    int j = 1;
    int k = k+1;
}

causes two compile-time errors, because j is referred to in the initialization of f before j is declared and because the initialization of k refers to k itself.

Initialization expressions for instance variables may use the simple name of any static variable declared in or inherited by the class, even one whose declaration occurs textually later. Thus the example:

class Test {
    float f = j;
    static int j = 1;
}

compiles without error; it initializes j to 1 when class Test is initialized, and initializes f to the current value of j every time an instance of class Test is created.

Initialization expressions for instance variables are permitted to refer to the current object this(§15.7.2) and to use the keyword super (§15.10.2, §15.11).