僕は昔からずーっと、finalを付けられる箇所にはすべて付けるようにしています。
ちなみにEclipseを使うと、セーブアクションで自動的にfinal宣言できるので超便利です。
不変オブジェクトを作るために、インスタンスフィールドをfinal宣言するようなケースは当然として、ローカル変数やメソッドの引数にも、finalを付けると素晴らしいメリットを享受できるのです。
その中でも一番重要なメリットは、
『意図していない代入を自動的にチェックできる』ということ。
例えば、誰かの書いたソースを読むときに
int value1 = 1; final String value2 = this.calcValue2();
という宣言があったならば、この時点で
『なるほど、value2はこの時点で値が固定なんだね』
ということが判明するわけです。
ということは、この宣言以降のコードを読むときにvalue2がどういう風に移り変わっていくのか気にする必要が全くないということです。
言い換えると、『value1の動向だけを注意すればよい』のだ、ということを示しています。
これだけ見ると
大したことがないように思えますが...
人間は、短期記憶のためのスロット(いわゆるレジスタ)を5〜6個*1しか持っていないと言われています。
その貴重なスロットを如何に使わずに済ませるか。コレはとても大事なことなのではないでしょうか。
...なんですけど、世間一般的には、finalを付けるという行為にかなり抵抗があるようです。
今やっている案件でも、『finalをつけるべし』という規約を提案をしたのですが、無碍に却下されてしまいました。
しかもその理由は『見た目が気持ち悪い』とかそんな感じの理由です。
せっかく、ほぼ副作用なく品質向上できる手段が存在しているというのに、それを活用しないのは、何とも勿体ない話だと思うんですけどねー。
せっかく強い型付き言語を使っているんだから、コンパイラの能力はできるだけ活用すべきだと思います。(final自身は型システムとは関係ないけど)
補足
書き忘れていましたが、クラスやメソッドは、設計上必要なもの以外はfinalにしてません。ココでのお話は、あくまでローカル変数とインスタンス変数に限定してます。
finalに関しては、どうやら昔から様々な考え方があるようですね。*2
僕は単に『ラクだから』付けているんですよねー。クラスの設計がどうこうというよりも。
何も考えず、とりあえず付けとけばいいじゃん、みたいなノリ。
finalが付くことで、ある種の情報(前述)が一目瞭然になるわけです。
もはやソースコメントと同じ、と言ってもいいかもしれません。
ま、そういうわけで、final病に長期罹患中だということは認めます(笑)
ちなみにsuper, this病も併発しているという。
更に今から4年前となると、Emacs病の隔離病棟に入院してた時期かな。
これはxkeymacs錠剤で症状を押さえてますが。
『清く正しく簡潔なコードを書けば、finalもsuperもthisもいらない』
(→そんなモノを使わなくても一目瞭然なコードを書けるはず)
とか言われたら、そりゃごもっとも、としか言えないわけですが。
まぁ何事もメリハリなのかな、と。