- - 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 15:36
あぶです。
【経緯】 最近、うちのプロジェクトにCheckStyleが導入され、 ウォーニング消しにあくせくで、手がつりそうです。。。 僕がどうこう言える立場ではないのですが、 特に気になるのは、変更しない変数にfinalを付けさせることです。 やたら多いので困っていますが、チェックから外す方針はないそうです。 そこで、思ったのですが、以下のように、 【本文】 引数にfinalを付けても、内容が変更されないことを保障できないじゃん。。。 ってことです。
C言語でも同じような問題があったような覚えがあるが、 どうやって対処したかは忘れました。。。 掲題のごとく、 引数で渡されたインスタンスの内容を変えないことを保障する ことはできないのでしょうか? 【投票】 変更しない変数にはfinalを付けるべきでしょうか? ※タイトル変えました。すみません。 [ メッセージ編集済み 編集者: あぶぽん 編集日時 2007-04-04 16:24 ] | ||||||||||||||||
|
投稿日時: 2007-04-04 15:45
【投票】
最後の選択肢…絶対に付けるな! です。 | ||||||||||||||||
|
投稿日時: 2007-04-04 15:53
悩みましたが、望ましいに1票。
引数に代入したらどういう挙動になるだろう?という疑問は 初心者が悩む点のひとつですから、そこに対してコンパイルエラーで 事前にはじき出せるというメリットがあります。 そういう意味ではつけておいたほうが望ましいかな、と。 ただし、本題であるところのインスタンスの内容を変更されないように という点に関してはなんら無力であるので、そういう意味では 「関係がない」に投じるのが正しいのでしょうかね。 | ||||||||||||||||
|
投稿日時: 2007-04-04 16:04
現在の Java の言語仕様であるかぎり、final は付けても意味がないと思います。付けることに手間と時間をかけるのは、手間と時間がもったいないから「付けないほうがいい」です。付けないとコンパイルエラーになるところ(インナークラス絡み等)にだけ、付けておけば良いと思います。 結局は、現在の Java の final は、変数に対する修飾なので、変数が指しているインスタンスがどうなろうと知ったことではないという仕様だからです。 これを補うために、setter をサブクラスにだけ付けて、引数の型をスーパークラスにしておくとか、immutable なラッパークラスに包むなど、いくつかのテクニックはあるかもしれませんが、コーディングの負荷が重すぎて、たかがそれだけのためにやるのは、逆にコードが見辛くなってしまい、やりたくはありません。 -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} | ||||||||||||||||
|
投稿日時: 2007-04-04 16:13
nagiseさん、はじめまして。
投票ありがとうございます。
プリミティブ型に関してはそうなんですよね。 参照型の場合は逆にまぎらわしくないですか? String型の場合どうなんだろうと思って試してみました。 結果、以下のようになんと代入ができてしまいます。
下のほうは納得がいきます。 きっと別のインスタンスが生成されているのでしょうね。
「場合による」でしょうか? もしくは「どちらでもいい」でしょうか? | ||||||||||||||||
|
投稿日時: 2007-04-04 16:20
unibonさん、ありがとうございます。
【投票】項目訂正! 「絶対に付けるな!」を「コンパイルエラーが出ない限り、絶対に付けるな!!」 に変更します。 確かにエラーでるときありますね。。。
手も時間もたっぷりとあるとしたら付けたほうがいいですか? | ||||||||||||||||
|
投稿日時: 2007-04-04 16:29
別の観点から言いますと、長年の経験から感じることですが、引数で渡されたインスタンスは、できるだけ get するだけにして、set はしないほうが良いです。 引数で渡されたインスタンスに対して set するのは、特別であり、javadoc にも目立つように書いておく、という風にしたほうが良いです。 たとえば、
の場合は、
などのような感じにします。(あくまでも例です。雰囲気だけのコードです。) #元のコードだと、src と dst が逆のような。 -- unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86} | ||||||||||||||||
|
投稿日時: 2007-04-04 16:31
匿名クラスから参照したいときにfinalを付けますが、
後は意味がないので付けません。 変数のスコープを極力狭くするのは、Javaではセオリーになりますが、 匿名クラスを使うときにfinalな引数は全て参照可能になります。 ですので、むしろ全てfinalというのはアンチパターンのような気がします。 (コンパイル時にはどうなるか、覚えていません・・・) |