Final Variables
A final variable is a variable whose value cannot be changed during its lifetime once it has been initialized. A final variable is declared with the keyword final in its declaration. Any attempt to reassign a value will result in a compile-time error.
Declaring a variable as final has the following implications:
- A final variable of a primitive data type cannot change its value once it has been initialized.
- A final variable of a reference type cannot change its reference value once it has been initialized. This effectively means that a final reference will always refer to the same object. However, the keyword final has no bearing on whether the state of the object denoted by the reference can be changed.
- The compiler may perform code optimizations for final variables, as certain assumptions can be made about such code.
For all paths of execution through the code, the compiler checks that a final variable is assigned only once before it is accessed, and when in doubt, the compiler issues an error (p. 232).
A blank final variable is a final variable whose declaration does not specify an initializer expression.
A constant variable is a final variable of either a primitive type or type String that is initialized with a constant expression. Constant variables can be used as case labels of a switch statement.
We distinguish between two kinds of final variables: final fields that are members in a class declaration and final local variables that can be declared in methods and blocks. A final field is either static or non-static depending on whether it is declared as a static or non-static member in the class.
Example 5.9 provides examples of different kinds of final variables. The declarations from Example 5.9 are shown here.
class Light { // (1)
public static final double KWH_PRICE = 3.25; // (2) Constant static variable
public static final String MANUFACTURER; // (3) Blank final static field
int noOfWatts; // (5) Non-final instance field
final String color; // (6) Blank final instance field
final String energyRating; // (7) Blank final instance field
// …
}
public class Warehouse {
public static void main(final String[] args) { // (15) Final parameter
final Light workLight = new Light(); // (16) Non-blank final local variable.
final Light alarmLight; // (20) Blank final local variable.
Light carLight; // (22) Non-final local variable.
// …
}
}
In the next two subsections we elaborate on final fields in classes and final local variables that can be declared in methods and blocks.