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.