|
Java uses the final modifier to declare that a piece of code or data is constant. When you apply the final modifier to a member variable, it simply means that the value in such variable is unchangeable. You can also apply this modifier to local variables. In fact, this is the only modifier that can be applied to local variables. You would mainly use the final variables to declare symbolic constants such as PI. For example,
final double PI = 3.142;
Initialization of final variables
The final variables basically represent a constant value. The Java compiler allows assigning of this constant value either at compile-time or at run-time. However, at compile-time itself it needs to make sure that a final variable will be assigned a constant value before it will be used. Therefore we will discuss initialization of final variables in detail as it is different from regular variable initialization[††††††].
Usually member variables are initialized automatically. For example, if you declare int i; as member variable, the variable i is automatically assigned a value 0. However, the final member variables are not initialized automatically. There is a good reason why. We know that once final variables are initialized, their value remains constant. Therefore if Java had initialized them automatically, they would get the default constant value[l5]. But you often want to declare a final variable to assign some constant value (other than the default values). Hence, Java does not automatically initialize them but expects you to initialize them explicitly.
Initialization of final instance variables
You can initialize a final instance variable at the time of its declaration. If not, you must initialized it in the constructor. In simple words, a final instance variable must be initialized before any instance creation. This will make sure that the final variable will have a constant value before anybody could access it. Listing 3.12 shows how compiler ensures that final instance variables are initialized before the instance of that class can be created and used.

The declaration of final variable country is invalid as it is not initialized anywhere. Being a final variable, it is not automatically initialized at the time of its declaration. In addition, it is not initialized in the constructor as well. Since Java does not allow un-initialized member variables, the class Timbuktu fails to compile with the compiler throwing an error saying something like, “The blank final field may not have been initialized”..
Initialization of final static variables
A final static variable can also be initialized at the time of its declaration. If not, it must be initialized before the class is loaded. Thus it is made sure that it is initialized before its possible use. Listing 3.13 shows how compiler ensures that final static variables are initialized before the class is loaded.

The declaration of final variable country is valid as it is initialized in a static block. This static block will be executed whenever the class is loaded in JVM. Since a Java class is loaded before it is referenced, it is guaranteed that the static final variable country is initialized before it could be accessed. On the other hand, the declaration of final variable latitude is invalid as it is not initialized anywhere.
|
|
You may find exam questions with code that does not initialize the final member variables. Note that such code does not compile. Sometimes the final variables are properly initialized, but they are reassigned to a new value. Such code also does not compile as reassigning a value to final variables is not permitted. |
Initialization of final local variables
Just like the final member variables, a final local variable need not be initialized at the time of its declaration itself. However you must explicitly initialize it before its first use. Listing 3.14 shows how the code fails to compile when the un-initialized final local variable is referenced in System.out.println().

This code will give compiler error complaining, “The local variable currency
may not have been initialized”. Note however that the final local variable may
remain un-initialized if it is not used at all. [l6]For
example, class Timbuktu would compile just fine if the method trading() does
not use the variable currency.
|
|
The important difference between final member variables and final local variables is that the final local variable may remain un-initialized if it is not used and the code compiles just fine. But the final member variables (static as well as instance) must be initialized even when they are not referred within a class. One of the reasons could be the difference between the scope of local and member variables. In case of local variables, the scope is limited to its containing block. For example, a method local variable’s scope is limited to the method body. That means it cannot be referred outside method body. Therefore if it is not referred within method body, it is OK for it to remain un-initialized as you cannot possibly refer it in any other way. On the other hand, the member variables can be referred by anyone with access to the class and these variables; hence compiler cannot let them remain un-initialized. |
Applying final to a method parameter
You can also declare method parameters as final. Such parameter(s) remains unchangeable within that method. You need not worry about initialization of a final method parameter as it would be always initialized with the value with which the method was invoked. Listing 3.16 illustrates how the code fails to compile when you try to reassign value to a final method parameter.
![]() |
|||
![]() |
|||
It is interesting to look a little deeper when we say final implies an unchangeable value. We know that a Java variable may hold either a primitive or an object reference as a value. If you declare a variable that holds a primitive value as final, then the variable forever (during its lifecycle) holds that value. For example, in final int i=5; I will hold the value 5 through out its scope. It cannot be assigned some other value. On the other hand, if a final variable holds a reference to an object, the reference must remain constant, not the object. In other words, you can change the object (rather state of an object) referenced by a final object reference by simply can be changed invoking methods on it. Listing 3.17 illustrates how a Mountain object can be changed using a final object reference everest.

Though you can modify an object referred by a final object reference variable, you cannot re-assign that reference variable to another mountain object. Therefore listing 3.17 illustrates how the code fails to compile when the final variable everest is reassigned to refer to another Mountain object. Since everest is a constatnt variable, it must point to the initially assigned Mountain object through out its scope.