- 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は一切保証も関与もいたしません。
投稿者投稿内容
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-04 18:11
【途中コメント】

おっと!

「絶対に付けるな」に一票入ったいっぽうで、
「望ましい」が増えて「付けなくていい」と同率ですが、

「望ましい」と答えたそのココロは?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-04-04 18:20
コードレベルでの小手先の最適化は、
むしろJVMの実行時の最適化の邪魔になる場合があるので、注意が必要ですよ。
よっぽろ素直に書いたほうが、実行時に最適化されやすくなります。

この辺はJVMの実装次第で、具合的なソースがあるわけではありませんが。。。
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-04-04 18:20
タイトルの観点とは異なりますが、メソッド内で同じ変数を何度も
使い回すような使い方は防げるので、よく使っています。
自分の書いたコードをコピペで使われてしまうことが多々ありまして、
メソッド内のコードをやたら長く書いてしまうような方に、
「変数の使いまわしはバグの元なので、少しは考えて下さいね」
という暗黙のメッセージとしての効果はあるかと。(多少)
私の周りにも、finalさえ付けていればインスタンスの中身を変更を抑止できる
と思っている方が案外多いみたいです。というか、そこまで深く考えてる
人が少ないのかもしれない・・・。

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

あぶぽんさんの書き込み (2007-04-04 16:13) より:
引用:

引数に代入したらどういう挙動になるだろう?という疑問は
初心者が悩む点のひとつですから、そこに対してコンパイルエラーで
事前にはじき出せるというメリットがあります。



プリミティブ型に関してはそうなんですよね。
参照型の場合は逆にまぎらわしくないですか?

String型の場合どうなんだろうと思って試してみました。
結果、以下のようになんと代入ができてしまいます。

コード:
void copy(final String src, String dst)
{
    // src = dst; これがエラーになりません
    // src = "ABC"; こちらもエラーになりません
}



下のほうは納得がいきます。
きっと別のインスタンスが生成されているのでしょうね。


いや、コンパイルエラーになりませんか?
少なくとも私の環境ではfinalな変数に値を代入しようとすればエラーとなります。
そのfinalが引数の時点で定義されようがそうでなかろうが同じでしょう。
どのバージョンのJavaでもこの挙動は変わらないはずですが…

コード:
public class FinalTest {
    static final int staticInt = 0;
    static final String staticString = "hoge";

    public static void staticHoge (final int paramInt, final String paramString) {
        paramInt = 2; // エラー
        paramString = "piyo"; // エラー

        staticInt = 5; // エラー
        staticString = "piyo"; // エラー
    }

    final int instanceInt = 2;
    final String instanceString = "hoge";
    public void instanceHoge(final int paramInt, final String paramString) {
        paramInt = 2; // エラー
        paramString = "piyo"; // エラー

        instanceInt = 3; // エラー
        instanceString = "piyo"; // エラー

        final int localInt = 3;
        localInt = 5; // エラー
        final String localString = "hoge";
        localString = "piyo"; // エラー
    }
}



引用:

あぶぽんさんの書き込み (2007-04-04 16:13) より:
引用:

ただし、本題であるところのインスタンスの内容を変更されないように
という点に関してはなんら無力
であるので、そういう意味では
「関係がない」に投じるのが正しいのでしょうかね。



「場合による」でしょうか? もしくは「どちらでもいい」でしょうか?


掲題と選択肢は無関係の事象と言っています。
finalを付けたところでインスタンスの内容が変更されることには
なんらの効果がないので別事象と捕らえるのが正しいと思います。

つまり、ガス欠に対してタイヤ交換をするようなものだ、ということです。
ですから「どちらでもいい」ではなく「無関係」としました。
あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-04 18:49
nagiseさん、皆さん、

【あぶの例】(訂正)
String型に関しては、なぜかそのときコンパイルエラーが出ませんでしたが、
エビデンスがありません。

再度、テストしてみたらコンパイルエラーがでました。

訂正します。

引用:

引用:

あぶぽんさんの書き込み (2007-04-04 16:13) より:

String型の場合どうなんだろうと思って試してみました。
結果、以下のようになんと代入ができてしまいます。

コード:
void copy(final String src, String dst)
{
    // src = dst; これがエラーになりません
    // src = "ABC"; こちらもエラーになりません
}



下のほうは納得がいきます。
きっと別のインスタンスが生成されているのでしょうね。


いや、コンパイルエラーになりませんか?
少なくとも私の環境ではfinalな変数に値を代入しようとすればエラーとなります。
そのfinalが引数の時点で定義されようがそうでなかろうが同じでしょう。
どのバージョンのJavaでもこの挙動は変わらないはずですが…

あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-04 18:54
皆さん、

本文は、引数で渡されたインスタンスの内容を変えないことを保障することに
ついて書いて、

投票は、「変更しない変数にfinalを付けるべきですか?」という質問でした。

まぎらわしいことをして済みません。

引用:

あぶぽんさんの書き込み (2007-04-04 15:36) より:

<< 省略 >>

【経緯】

<< 省略 >>

【本文】
引数にfinalを付けても、内容が変更されないことを保障できないじゃん。。。

<< 省略 >>

掲題のごとく、
引数で渡されたインスタンスの内容を変えないことを保障する
ことはできないのでしょうか?

【投票】
変更しない変数にはfinalを付けるべきでしょうか?

※タイトル変えました。すみません。




あぶぽん
大ベテラン
会議室デビュー日: 2005/10/20
投稿数: 205
投稿日時: 2007-04-04 19:02
かつのりさん、

おそらく、アクセッサにfinalを付けることに関してのコメントかと
思いますが、

初期のころ(JDK1.0.x)には、アクセッサがインライン展開されないとか、
小さいfor文が展開されないなどの話題がよくのぼっていました。

アプレットが遅いっ! っていっている時代ですから、
そのときのクセです。

C++でもinlineとか書いてましたから。。。
記憶が定かでないのであまりツッコまないでください。。。


引用:

コードレベルでの小手先の最適化は、
むしろJVMの実行時の最適化の邪魔になる場合があるので、注意が必要ですよ。
よっぽろ素直に書いたほうが、実行時に最適化されやすくなります。

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-04-05 10:22
おや?
「投票:」の部分はタイトル変更が反映されないのですね。

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