引数final

Java の言語仕様で、メソッドの引数にも final 修飾子を与えることができる。

public void execute(final List list) {
    //
}

これ、今までずーっと意味を勘違いしてました。「引数 object への変更は認めない」ではなくて、「引数 list への代入は認めない」という意味のようだ。なので、次のリストのようなことになる。

public void execute(final Object object) {
    list.add("aaa"); // これはOK
    list = new ArrayList(); // これはコンパイルエラー
}

つまり、引数 final は、その引数インスタンスそのものに対する意味であって、内部データを保護する意味はないのね。完全に期待していたのと違った意味付けになっていて、ホントに狼狽した。せっかくの修飾子なんだけど、ここに final を付けることの方が、余計に意味が分かりにくくなっている気がする。

ただ、唯一意味があるのは、メソッド内部で匿名クラスを使用するような場合。

public void add(Button button, final Label label) {
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            label.setText("hoge");
        }
    });
}

このようなケースでは、引数 Label に final 修飾子が付いていないと、逆にコンパイルエラーになってしまう。(メソッド内部で final 宣言した変数に入れ替えても動くので、引数 final が必須ではないけれども)

自分が言語仕様をちゃんと把握してなくてダメだって話なんだけど、またいつか別のプロジェクトではまりそうな気がするので、コーディング規約として禁止したいなあ。アノテーションもそうだけど、余計な意味付けがなされていると、深読みしちゃいますよネ。ね?

このエントリーのトラックバックURL
http://www.deftrash.com/admin/mt4/mt-tb.cgi/470