final のススメ
2007.09.26
パズルです。ありがちなことですが、Java プログラムで修正が発生しました。その内容は、
古いインターフェイスを廃止したので、新しいインターフェイスに派生クラスを書き換えるべし
というものです。が
- 1. 派生クラスの数が半端じゃないです。
- 2. この派生クラスの全部に修正対象メソッドがあるわけではなく、それは確認しなきゃならない...
- 3. その派生クラスがアプリ全体に散らばっていて、一覧するのも厄介だ....
というケースで、一番簡単な対象クラスのチェックはどうすればいいでしょう?
(今風に回答がすぐに見えないように改行入れます)
それはですね、
廃止対象メソッドを、final 宣言してコンパイルする
というやり方です(苦笑)。final 宣言されたメソッドは、「上書き禁止」ですから、廃止メソッドを含んだクラスはすべてコンパイルエラーになります。ですから、それをツブしていけばいいわけで、修正後さらにコンパイルすれば、修正落ちがないことも確認できるわけです。
この使いかたはちょい邪道ですが、final 宣言自体は結構使いでのある Java 言語仕様だってご存知でした? この使い方は、後々同じ継承クラスを使う人に、「このメソッドは上書きすべきでない」ことを、伝えるというのが本来の意味ですが、それを作業上先取りすれば、こういうことも出来ちゃうわけです。まあ、それだけではなくて、final 宣言は、
- 1. いわゆる Immutable なデータオブジェクトの作成のときに使う。これメチャ重要なテクニックですから、憶えるといいですよ。
- 2. ユーティリティクラスなどを final class として宣言する
- 3. 上書きしたらそのクラスの意義を失うようなメソッドであることを、特に使う人に伝えたい
というような「基底クラスを作ったプログラマの意図」を、継承クラスの作成者に伝える、というあたりでの重要な機能を持っているわけです。final 宣言の一番よく使われるケースは言うまでもなく、
ある変数を定数扱いにしたい
というものですが、それの陰に隠れるはもったいない機能がいろいろとある...というのを使って実感してみましょう!
とはいえ、変数引数の final 宣言については、私の立場は「付けない方がいい」です.....だってあれ、昔ながらの「C言語で const 修飾は付けるべきか?」問題と同じで、付けてもインスタンスへの直接の代入を検出するだけで、本来「こうだったらいい」仕様の「インスタンスの中身の全般的な変更不可」は全然実現できないわけです。だったら final 引数宣言は(内部無名クラスに渡す引数の制限で使うケースは別として)無意味であり、誤解の元のように思います...
どっちか言えば、「この引数はこのメソッドで積極的に変更される」というのを明示するような、そういう修飾がある方のが有益のような気がします....(あ、そういうアノテーション作るって意味ありますね)。
投稿者 : 杉浦 こずえ | 投稿日時 : 2007.09.26 17:35
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





