- - 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-05 13:51
おっ。思っていた方向に話題が進んだみたいですね。 スルーされてたので寂しかったです。。。
メソッド単位にすると、C++のconst/mutableのようなことになるので、 クラス単位の方がよさそうに思います。 クラス全体がimmutableであれば、 使う側は個々のメソッドまで考えずに不変であることを利用できます。 immutableなクラスのインスタンス変数がconstではなくfinalだとすれば、 必要ならばmutableな状態を内部クラスなどに持たせればよいわけですし。 immutableなクラスでインスタンス変数の更新を行いたい理由の多くは、 パフォーマンス向上のためのキャッシュなどの目的が多そうに思うので、 そういった実装上の詳細は隠したまま、immutableを維持すべきだと思います。 | ||||||||
|
投稿日時: 2007-04-05 14:19
あ〜。なるほど。考えが抜けてました。 class修飾子immutable案だとjava.io.Serializableのようなことになりますね。 こちらは直列化の際に動的にエラーとする方式ですが… immutable性をコンパイル時で検出したいとなれば難しい感じですね。 # 配列をどう扱うんだ、という話もありますね アノテーション@immutable案は実現可能かもしれませんね。 不変オブジェクトを作成する側が責任を持ってメソッドをマークしないと いけないという難点はあるのですが、逆に言えば機械処理をあきらめることで 実現させる際の難易度を落としているのですよ。 余裕があれば実装を試みてみたいネタですね。 | ||||||||
|
投稿日時: 2007-04-05 14:22
あしゅさん、皆さん、
mutable/immutableの話が、僕には難しくなってきました。 簡単に質問しますが、その機能があれば、以下のようになるということでしょうか?
# まあこんなコピーメッソッドは作りませんが、サンプルということで。。。 つまり、不変オブジェクトが作れると。 | ||||||||
|
投稿日時: 2007-04-05 14:48
一旦論点整理です。
まず、immutableなクラスというのは現時点のJavaでも作成可能です。 java.lang.Stringなどが有名ですね。 クラス全体をimmutableとして設計できるケースはそのようにすればよいのですが、 言語の修飾子なりアノテーションなりで明示できるとよいね、 というあたりが結論ということでよろしいでしょうか。 「不変オブジェクト」というと「不変クラス」との混用が多いようなので 「不変インスタンス」という用語を使いましょう。 可変なクラスの特定のインスタンスといいますか、特定の変数のみ不変としたい。 つまりfinal修飾子を付けて宣言した変数の「参照」ではなく「実態」を不変としたい。 というのがあぶぽんさんの求めるものですよね? 既存のJavaの機能で実現するとしたらアノテーションを使うしかないのではないでしょうか。
ということができるようにならないでしょうかね、という話ということでよいでしょうか。 | ||||||||
|
投稿日時: 2007-04-05 15:23
この方向性だと、メソッド毎にmutable/immutableを定義しないと 使い物にならなくなるので、C++のconst関数と同じになってしまうのでは? それに、個々の変数に対する修飾子(アノテーションでも)として定義すると、 どうしても利用する側の判断になってしまうので、実質的な強制力も低く、 final同様、意味の薄いものになってしまうのではないでしょうか。 | ||||||||
|
投稿日時: 2007-04-05 15:35
nagiseさん、
ご解説ありがとうございます。 皆さんの意見からすると、RubyやPHPでは実現できている機能なんですね。 Javaも言語仕様として提言すべきだと思います。 また、あしゅさんの意見では、
とありますが、 C++ではどのような点が問題になっているのでしょう? | ||||||||
|
投稿日時: 2007-04-05 15:57
実現可能性側から考えた話ですので利便性には確かに疑問がありますね。 寡聞ゆえC++のmutableキーワードを知らなかったのですが、 確かに対象クラスの作成者に大きな負担がありますし、信頼性も薄いでしょうね。 状態変更を伴うメソッドというのが容易に判断できないですからね。 そこを製作者責任ということにすれば実現可能という話ですから。 もっと単純にgetter以外を呼ぼうとしたらOUT!という作りであれば アスペクト指向な環境であれば比較的容易に実現できるのかもしれませんね。 結局、利用可能なメソッドがマークされていないと変な裏道ができちゃうわけですが… クラスレベルで不変クラスにできるならそれが一番だとは思います。
RubyやPHPはかじった程度なのですが、インタープリタの実装でがんばれば 確かに可能そうですね。もしJavaに盛り込むとしたらVM側に盛り込めば 動的検出にはなりますが可能なのかもしれませんね。 考慮すべき問題点としてマルチスレッド時の整合性ということも考えると 変数ではなくインスタンス単位で不変とするぐらいしか無理なのかもしれませんね。 | ||||||||
|
投稿日時: 2007-04-05 16:27
みなさん、
完璧を目指すと結局、言語仕様を変えることになるかと思いますが、 僕が、今、一番問題にしているのは、以下のような全く予測不可能な ところでインスタンスの内容が変えられてしまうことです。
こういうことをされると、デバッグにすごく手間がかかるので。 それならいっそfinalなんて付けなきゃいいのに。。。紛らわしい というわけで、「絶対に付けるな」のうちの一票は僕でした # 1行目になぜfinalを付けなければならないのかというのも問題ですが。 # CheckStyleの(いや、うちの規約の)せいです。。。蒸し返してすみません。 |