- - 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% | |
|
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-04-04 16:40
引数にインスタンスを渡す場合、
・状態の変更可能なインターフェイスの隠蔽 ・クローンを渡す というのがよくあるパターンかと思います。 状態の変更可能なインターフェイスの隠蔽ですが、
と、読み込み専用のインターフェイスを用意して、 実装で書き込みをできるようにします。 渡す場合は、
というメソッドを用意すれば変更可能なインターフェイスが隠蔽されます。 クローンを渡すというのはフィールドの配列を返すときに、 フィールドが参照している配列ではなく、 その配列のクローンを返すということをよくやると思いますが、同じことです。 | ||||||||||||
|
投稿日時: 2007-04-04 16:59
unibonさん、かつのりさん、ありがとうございます。
【unibonさんのコード例】 普通にオブジェクト指向開発してきた人なら、まずそう考えますよね。 しかし、うちのプロジェクトのコードをよくよく見てみると、 値を二つ以上返したいときに、メソッドの中で書き換えちゃうみたいです。 最初は、値を変更しませんよというアピールのためにだけでも、 付けても害はないかなとも思っていましたが、 結局、開発者の良識に任せるしかないのなら、 final付ける意味ってないような。。。ホント、徒労ですね。 【かつのりさんのコード例】 かっちり、決めたいときはそうしたいですね。 しかし、interfaceを使うとは考えつきませんでした。 単にsetterを隠蔽するのかと。。。 これって、ナントカ指向かなにかっぽいですね。 # インターフェイスドリブンかな? さっそく、いただいちゃいます! ところで、かつのりさんはどうして 「コンパイルエラーが出ない限り、絶対に付けるな!!」じゃないんですか? | ||||||||||||
|
投稿日時: 2007-04-04 16:59
CheckStyle は使ったことがないのですが、final が付いていないと警告が出るということでしょうか。警告ツールが警告を出すから、一律に final を付けるというのは、機械に人間が使われているようであり、本末転倒だと思います。私だったらその「チェック」から外します。 (もっとも、私も、普段は、eclipse のコンパイラーの警告は強め(警告がたくさん出るように)にして、出た警告はせっせと消します。しかし final を付けようとは思いません。)
たっぷりあったら、ほかのこと(もっと有意義なリファクタリングや休憩)に使ったほうが良く、やはり final は付けないほうがいいと思います。 -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} | ||||||||||||
|
投稿日時: 2007-04-04 17:10
付けなくていいに一票入れました。
すでに前の書き込みにあるように、 インスタンスの中身を書き換えない事を保証するには 引数となるクラスの側がimmutableでなければならないからです。 引数とローカル変数の寿命はメソッド内だけなので一目瞭然ですし。 クラス変数/インスタンス変数の場合は積極的にfinalにしています。 寿命の長いオブジェクトの状態管理は思っているより難しいものです。 可能であるのならimmutableにしてしまいます。 | ||||||||||||
|
投稿日時: 2007-04-04 17:15
unibonさん、
CheckStyleのfinal警告は、以下のようなコードも finalが必要と言われるんですよ!
たしかに、sample1変数(アドレス値)は変わってないのですが。。。 [ メッセージ編集済み 編集者: あぶぽん 編集日時 2007-04-04 17:21 ] | ||||||||||||
|
投稿日時: 2007-04-04 17:33
独り言です。
どこかで仕様案が出ているかもしれませんが、アノテーションもしくは マーカインタフェースでImmutableを表現できると良さそうな気がします。 コンストラクタ以外ではインスタンス変数を全てfinalと同様に扱う仕様で。 互換性を考えるとVMではなくコンパイラレベルで行うのが妥当でしょう。 #もしかしたらC++のmutableみたいなものが必要になっちゃうかも? rubyのfreeze()のようにタイミングを選べるのも便利ですね。 | ||||||||||||
|
投稿日時: 2007-04-04 17:40
私の場合は単純に、目的に合う場合にのみにfinalを付ける派ですね。
目的外なら付けません。面倒なので。 私もFindBugsを使って警告にしたがって修正もしますが、全てではありません。 CheckStyle主義すぎるのも、いかがなものかと思います。 | ||||||||||||
|
投稿日時: 2007-04-04 18:07
僕の場合は、finalを使うのは定数とアクセッサだけと決めています。
(アクセッサに付けるのは、コンパイラにインライン展開をお願いするため) だから、finalの手戻りが大きいんですよね。。。 CheckStyleが悪いわけではありません。設定ではずせるのですから。 しかし、目の前の仕事から逃げるわけではありませんが、 前述のとおり、参照型の変数にはすべてfinalを付けることになります。 (値は変わっても、参照元アドレスは変わらないので) 。。。美しくないという理由もあってもいいかと思います。 |