2013-08-14 18 views
31

最終的なローカル変数を使用することができるかどうかは疑問でした。継承が現れると、変数はオーバーライドされません。例えばJavaでの最終的なローカル変数の使用

public static void main(String args[]) { 
    final String data = "Hello World!"; 
    System.out.println(data); 
} 

以下の例のような簡単なコードでは、非常に単純なものであり、関連するコードではないかもしれないが、問題をよりgeneric.Iは、コードの多くを見てきている(全て最終有する主な機能に組み込まれローカル変数)ローカル変数を宣言することは、同じ関数自体では編集できないという点以外は最終的なものではありませんか?

+0

なぜそれが必要ですか?あなたはそれをハードコーディングしたり、クラス内でプライベートファイナルを持つことができます –

答えて

57

第1に、変数が「上書きされる」という部分については、finalは2つの非常に異なる意味を持っています。クラスとメソッドについては、継承についてです。変数の場合は、読み取り専用です。

最終的なローカル変数には、ローカル(通常は匿名)内部クラスで使用できる重要な機能があります。非最終的な局所変数は、できません。それは私の経験では、ローカル変数のためのfinalの主な使用です。スタイルの問題として、一部の人々は、彼らがローカル内部クラスに変数を取り込むないいる場合でもfinalを使用したいという

public void foo() { 
    final String x = "hello"; 
    String y = "there"; 

    Runnable runnable = new Runnable() { 
     @Override public void run() { 
      System.out.println(x); // This is valid 
      System.out.println(y); // This is not 
     } 
    }; 
    runnable.run(); 
} 

は注意してください。私は間違いなくfinalがデフォルトであるが、 "non-final"のための別の修飾子には快適だと思いますが、どこに明示的に修飾子を追加すると気が散るのです。

+0

私はそれが最適化を実行するのに役立つと感じています。この最終変数の値が変更されることはないため、JVMはこの変数の値をキャッシュしてパフォーマンスを向上させます。 –

+9

@Ankurこれは長い間そうではありませんでした。コンパイラは、変数が変更されているかどうかに応じて非常に簡単に修正し、それに応じて最適化することができます。ここでそのような[別のSOの答え](http://stackoverflow.com/a/4279442/2071828)です。 –

+2

@Jon Skeetこれらの変数は匿名の内部クラスによってアクセスできるので、ローカルスコープを超えて存在すると仮定するのは正しいですか? – Ahmed

9

最終的なローカル変数は匿名の内部サブクラスからアクセスできますが、最後のローカル変数はアクセスできません。

5

はい、そこにある私たちは、通常、それを使用することができ、小さなexpample -

スニペット:匿名内部クラスでの使用の

final Boolean data = Boolean.TRUE; 
button.addListener(SWT.Selection, new Listener() { 
    public void handleEvent(Event event) { 
     if (data) { 
        .... 
       } 
     } 
}); 

その一例。内部変数の中でローカル変数を使用する場合は、finalにする必要があります。

8

はい、使いやすさは次のとおりです。 - ローカルのfinal変数は、メソッドの内部クラスによってアクセス可能です。 ローカル変数はスタック上に存在し、メソッドの存続期間中にのみ存在しますが、Innerクラスオブジェクトはより長く存続するため、内部クラスは最終的でないローカル変数にはアクセスできません。 しかし、一度変数がfinalになると、内部クラスは値が変更されないようにして、使用する最終ローカル変数のプライベートコピーを保持します。

+0

これは妥当なものであると判明した唯一の答えです。良い1 @ Krushna – DJphy

3

あなたは読みやすくするためfinalキーワードを使用し、それを変更したり、ここのような匿名クラスにされていない保証することがあります

final String s = "hi"; 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      // can use s variable here 
     } 
    }).start(); 
3

それは誰でもそれを書いたことはデータの値が shouldn」ことを知っていたことを他のプログラマに伝えます一度割り当てられた変更。私の意見では特に、パラメーター変数をの最終と宣言するのは良い習慣です。

5

完璧な答えJon Skeetしかし、最終的な変数の別の(少しの)利点があります。

コンパイラは、最終変数が1回だけ確実に設定されるようにします。

変数を初期化しなければならず、値の計算は複雑です(if-then-else内の複数のif-then-else)。ある条件で変数を初期化しないコードを書くかもしれません(あるいはそれを2回初期化するかもしれません)。もちろん、これはバグです。変数をfinalにすると、コンパイラは最終変数が一度だけ設定されていることを確認できます。あなたがバグを持っているかどうかをすぐに知ることができます。

私が言ったように、ほとんど利点はありませんが、まだ便利です。

4
は、Javaでの最後のローカル変数の

使用

finalフィールド、パラメータ、およびローカル変数は読み取り専用を(オブジェクトのアイデンティティではなく、その状態を意味する)です。

+0

確かに、塩の価値のあるコンパイラは変数が決してメソッド内で変更されないことを認識し、最終決定唯一の利点は、コードを読んだり修正したりする人が意図を知ることで、誤って値を再割り当てすることを防ぐことができます。 –

関連する問題