Everything's Final
"Every variable declaration you possibly can" sounds a bit extreme, but final
is actually beneficial in many ways. Sometimes I wish that final
was the default behavior, and required no keyword, but true "variables" required a variable
modifier. Scala adopted something like this approach with its val
and var
keywords—using val
(the final
-like keyword) is strongly encouraged.
It is especially important to carefully consider whether each member variable is final
, volatile
, or neither, because the thread safety of the class depends on getting this right. Values assigned to final
and volatile
variables are always visible to other threads, without using a synchronized
block.
For local variables, it's not as critical, but using final
can help you reason about your code more clearly and avoid some mistakes. If you don't expect a value to change within a method, say so with final
, and let the compiler find unnoticed violations of this expectation. I'm not aware of any that do currently, but it's easily conceivable that a JIT compiler could use this hint to improve performance too.
In practice, I don't declare local variables final
whenever I could. I don't like the visual clutter and it seems cumbersome. But, that doesn't mean it's not something I should do.
A proposal has been made to add the var
keyword to Java aimed at supporting type inference. But as part of that proposal, there have been a number of suggestions for additional ways of specifying local variable immutability. For example, one suggestion was to also add the key word val
to declare an immutable variable with inferred type. Alternatively, some advocate using final
and var
together.
final tells the reader that the value or reference assigned first is the same at any time later.
As everything that CAN be final IS final in this scenario, a missing final tells the reader that the value will change later, and to take that into account.
This is a common idiom for tools like PMD. For example, below are the corresponding rules in Checkstyle. It's really a matter of style/preference and you could argue for both sides.
In my opinion, using final for method parameters and local variables (when applicable) is good style. The "design for extension" idiom is debatable.
- http://checkstyle.sourceforge.net/config_misc.html#FinalParameters
- http://checkstyle.sourceforge.net/config_design.html#DesignForExtension
- http://checkstyle.sourceforge.net/config_coding.html#FinalLocalVariable