final means, this value won’t be changed
hereafter.
Advantages of using final
final is one of the most under-used features of
Java. Whenever you compute a value and you know it will never be changed
subsequently put a
final on it. Why?
- final lets other programmers (or you reviewing your
code years later) know they don’t have to worry about the value being
changed anywhere else.
- If you get in the habit of always using final, when
it is missing, it warns people reading your code there is a redefinition of the
value elsewhere.
- final won’t let you or someone else
inadvertently change the value somewhere else in the code, often by setting it
to null. final helps
prevent or flush out bugs. It can sometimes catch an error where an expression
is assigned to the wrong variable. You can always remove it later.
- final helps the compiler generate faster code,
though I suspect a clever compiler could deducing finality, even when the final
is missing. final values can sometimes be inlined
as literals. They can be further collapsed at compile time in other final
expressions.
- I have got into the habit of using final everywhere,
even on local variables, and if I am in doubt, I use final
on every declaration then take it off when the compiler points out that I
modified it elsewhere. When I read my own code, a missing final
is a red flag there is something complicated going on to compute a value.
- A little known feature of Java is blank finals. You
can declare member variables final, but not declare
a value. This forces all constructors to initialise the blank final
variables. A final idiom I often use looks like
this:
If I were redesigning Java, I would make all variables final by default. This
would reduce the visual clutter and make the rarer var
variables stand out.
final contexts
The term final is used in a number of contexts. static
final variables are close to constants in other languages. final
classes may not be subclassed. final methods may
not be overridden. On methods private implies final,
but on variables does not. Marking things final has
two purposes: efficiency and safety. The compiler can perform various
optimisations knowing the value cannot change. Hotspot and optimising compilers
now do this anyway, whether or not you declare methods final,
so using final purely for efficiency is no longer
recommended. The compiler can also check to ensure you do not inadvertently
attempt to change the value after computing its value once where it is defined.
You can have both final instance and final
static variables. final statics are more
common. When you know the value of a constant at compile time you might as well
make it static. It takes up less room, just one
copy per class instead of one copy per object. It is also faster to access a
static constant than an instance constant. However, if you don’t know the
value of the constant until instantiation time,
you have to make it an instance constant.
final is not the same as C++ const
If you have a final reference to an object or array,
it does not stop you from changing the fields in the object or elements
of the array. final just stops you from pointing
that reference variable to a different object or array. If you want to protect
the object from changes, you must make it immutable,
namely remove any setter methods from its class definition. Java’s final
is not as flexible and powerful as C++ const,
however, Java’s final is less error prone.
My Philosophy
I use IntelliJ IDE. It strenuously urges you to mark final
any class that is not currently overridden. This helps document which
classes currently have overrides and which don’t. final
also helps the compilers, JITs and AOTs to generate faster code. Since I always
distribute source code, I figure you can easily remove the finals
whereever they get in the way of your own overriding and extending. If I were
distributing only class files, I would have to be much more careful about finals,
since every one would prevent you from extending that class or method.
The problem is, when I release updated source, you have to re-remove the finals
to make your code work.
Learning More
If you are a language lawyer, you might enjoy digging into the JLS for its
academic descriptions on how final is used.