What Field Modifier final Means
This section looks at final, which makes something constant. Why was the word "const" or "constant" not chosen? Because "final" can also be applied to methods, as well as data, and the term "final" makes better sense for both.
A class or a class member (that is, a data field or a method) can be declared final, meaning that once it is given a value it won't change. We will look at what it means for a class or a method not to change in Chapter 8. A couple of final data declarations are:
final static int myChecksum = calculateIt(); final Timestamp noon = new Timestamp(12, 00, 00); final int universalAnswer = 42;
When a reference variable is declared final, it means that you cannot change that variable to point at some other object. You can, however, access the variable and change its fields through that final reference variable. The reference is final, not the referenced object.
JDK 1.1 introduced the ability to mark method arguments and variables local to a method as final, such as:
void someMethod(final MyClass c, final int a[]) { c.field = 7; // allowed a[0] = 7; // allowed c = new MyClass(); // final means this line is NOT allowed a = new int[13]; // final means this line is NOT allowed }
Programmers rarely use this, because it clutters up the signature and makes the parameter names harder to read. That's a pity. Marking a declaration as final is a clue to the compiler that certain optimizations can be made. In the case of final primitive data, the compiler can often substitute the value in each place the name is used, in an optimization known as constant propagation. As my friend, talented compiler-writer and builder of battle robots Brian Scearce pointed out, that in turn may lead to other optimizations becoming possible.
The "blank final variable"
JDK 1.1 also introduced something called a blank final variable, which is simply a final variable (of any kind) that doesn't have an initializer. A blank final variable must be assigned an initial value, and that can be assigned only once. If you give a value to a blank final in a constructor, every constructor must give it a value. This is because you don't know which constructor will be called, and it must end up with an initialization.
class Employee { final String name;// blank final variable - has no initializer Employee (String s) { // constructor name = s; // the blank final is initialized } // more stuff }
Use a blank final when you have a value that is too complicated to calculate in a declaration, or that might cause an exception condition (more on that later), or where the final value depends on an argument to a constructor.
That completes the description of static and final. The next section, Why Enumerate a Type?, explains a new feature in Java, the enumerated type, which is built up from final static values.