- PR -

変更しない変数にfinalを付けるべきですか?

投票結果総投票数:69
必須 2 2.90%
望ましい 25 36.23%
場合による 7 10.14%
どっちでもいい 1 1.45%
付けなくていい 28 40.58%
付けないほうがいい 4 5.80%
付けるな 0 0.00%
絶対に付け 2 2.90%
  • 投票は恣意的に行われます。統計的な調査と異なり、投票データの正確性や標本の代表性は保証されません。
  • 投票結果の正当性や公平性について、@ITは一切保証も関与もいたしません。
投稿者投稿内容
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-04-05 11:39
全部の投稿を追えているわけではないのですが、「付けなくていい」に一票いれました。

既に出ている大方の意見と一緒ですが、
・インスタンスの中身そのものを保護することを保証できるわけではない
・引数の変数に代入できてしまうことに起因するバグは希なので、final をいちいち付けることによるコストに見合わない
・つける習慣がない
といった理由からです。

現状インスタンスの状態を変えてしまうメソッドと、変えないメソッドをコンパイラに区別させる方法がありませんから、誤って引数のインスタンスを汚してしまうことをコンパイラレベルで防止させることはできませんね。
もしアノテーションなどでインスタンスを汚すメソッドなのか、そうでないのか宣言できるような規約があったとしてもイチイチ宣言するのは面倒すぎるのでつかわないと思います・・・。

[ メッセージ編集済み 編集者: インギ 編集日時 2007-04-05 11:40 ]
ひろ@ya
大ベテラン
会議室デビュー日: 2006/02/23
投稿数: 168
投稿日時: 2007-04-05 11:43
参考にどうぞ。
http://javafaq.jp/S012.html#S012-15
ふーばー
大ベテラン
会議室デビュー日: 2003/06/05
投稿数: 163
投稿日時: 2007-04-05 11:50
私はコーディング標準として「絶対 final を付けろ」を入れています。
私自身*に*は必要ないと思っています。ですが、変なバグを埋め込む人が
いるのでこうしています。
引数にパスが渡されるメソッドの仕様変更で、パスを保存しておく処理が追加になった。
コード:
void foo(String path) {
 :
 :
  save(path); // 追加
}


と追加するわけです。普通ならこれでいけると思うんですが、要求通りに動かない。
よくよく調べると、
コード:
path = path.substring(...); // ディレクトリ名を取得


という処理が入っていた、なんてことがたまにあります。

スキルの低い開発者に自由にさせない「縛り」の一つとして、final を徹底させて
います。
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2007-04-05 12:44
「付けないほうがよい」にしました。
私自身は、インギさんとまったく同じ理由で付けてないのですが

引用:

既に出ている大方の意見と一緒ですが、
・インスタンスの中身そのものを保護することを保証できるわけではない
・引数の変数に代入できてしまうことに起因するバグは希なので、final をいちいち付けることによるコストに見合わない
・つける習慣がない



引用:

私の周りにも、finalさえ付けていればインスタンスの中身を変更を抑止できる
と思っている方が案外多いみたいです。というか、そこまで深く考えてる
人が少ないのかもしれない・・・。



と思ってる人がいるのであれば、付けることで不変オブジェクトになると勘違いされると
困るので、逆に付けない方が良いと思いました。

※Effective Java読むまで私もインスタンス変数全部にfinalを付ければ、
不変オブジェクトになると勘違いしてましたし・・・<防御的コピーが必要です

もちろん、代入を防止させるためであれば、付けるべきだと思います。
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-04-05 13:15
引用:


引用:

私の周りにも、finalさえ付けていればインスタンスの中身を変更を抑止できる
と思っている方が案外多いみたいです。というか、そこまで深く考えてる
人が少ないのかもしれない・・・。



と思ってる人がいるのであれば、付けることで不変オブジェクトになると勘違いされると
困るので、逆に付けない方が良いと思いました。

※Effective Java読むまで私もインスタンス変数全部にfinalを付ければ、
不変オブジェクトになると勘違いしてましたし・・・<防御的コピーが必要です

もちろん、代入を防止させるためであれば、付けるべきだと思います。



finalを付ける事で、ちょっとfinalの動作を知り始めた人にとっては、
かえって間違えを誘発させる危険性もあるということですね、なるほど。
やはり、不変とすることができる識別子を言語仕様に追加してもらうの
が一番良いみたいですね。
PHP5の__setみたいな仕組みがあれば、変更の許可・不許可を柔軟にコントロール
できるかもしれない。


nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-04-05 13:27
引用:

小僧さんの書き込み (2007-04-05 13:15) より:
finalを付ける事で、ちょっとfinalの動作を知り始めた人にとっては、
かえって間違えを誘発させる危険性もあるということですね、なるほど。
やはり、不変とすることができる識別子を言語仕様に追加してもらうの
が一番良いみたいですね。



classキーワードへの修飾子immutableを新設し、immutable classは
インスタンス変数が全てfinalである必要がある、といった具合でしょうか。

setter以外にも内部状態を変更させるメソッドが存在しえますから
外からインスタンスの不変を保障することは論理的に不可能に思えます。

いや、まてよ。
アノテーション@immutableを用意して、クラス側で状態変更を伴わない
メソッドをマーキングしておけば、immutableとされた変数が
状態変更を伴うメソッドの呼び出しをするのを防げるかもしれませんね。
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-04-05 13:34
引用:

いや、まてよ。
アノテーション@immutableを用意して、クラス側で状態変更を伴わない
メソッドをマーキングしておけば、immutableとされた変数が
状態変更を伴うメソッドの呼び出しをするのを防げるかもしれませんね。




この案、面白いですね。

__set()に加えて、PHP5の__call()みたいな機能が言語仕様で・・・
しつこかったですね、すみません。



かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-04-05 13:48
フィールド自体がfinalでもインスタンスの変更自体は可能なので、
再帰的に・・・となると大変っぽい感じがしますね。


スキルアップ/キャリアアップ(JOB@IT)