2012-04-26 19 views
14

メソッド内で定義されたInner classがそれを使用する必要がある場合、なぜlocal variablefinalと宣言する必要がありますか?内部クラスとローカル変数

例:

class MyOuter2 { 

private String x = "Outer2"; 

void doStuff() { 
    final String y = "Hello World"; 

    final class MyInner { 

     String z = y; 

     public void seeOuter() { 
      System.out.println("Outer x is "+x); 
      System.out.println("Local variable is "+y); 
      MyInner mi = new MyInner(); 
      mi.seeOuter(); 
     } 
    } 
} 

}

文字列が最終一定にする必要があるyなぜ?どのように影響を受けますか?

+0

このディスカッションはhttp://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – kosa

+0

の可能な複製を参照してください[[内部の最終的な変数を参照できません]別のメソッドで定義された内部クラス](http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a- differen) –

+0

[Javaのローカル最終変数に関する質問](http://stackoverflow.com/questions/5947352/question-about-local-final-variable-in-java) – Lion

答えて

13

答えは2つのスコープが異なることです。その変数は、内部クラスがアクセスする前に変更される可能性があります。それを最終的にすることはそれを防ぎます。

+2

これはjava 8で変更されています。http://docs.oracle.com/javase/tutorial/java/japan/localclasses.html#accessing-members-of-an-enclosing-class – ohcibi

3

これはプログラマが間違いをするのを防ぐためだと思います。この方法では、コンパイラは、そのメソッドを終了するときに変数にアクセスできなくなることをプログラマに思い出させます。これはループで重要です。

public void doStuff() 
{ 
    InnerClass cls[] = new InnerClass[100]; 
    for (int i = 0; i < 100; ++i) 
    { 
     cls[i] = new InnerClass() 
     { 
      void doIt() 
      { 
       System.out.println(i); 
      } 
     }; 
    } 
} 

doIt()メソッドが呼び出されると、何が印刷されるのですか?ループ中にiが変更されました。 混乱を避けるためには、変数をローカル変数にコピーするか、変数finalを作成する必要がありますが、ループすることはできません。

1

あなたの内部クラスは最終的なものなので、最後のエンティティの内部から何かを変更することはできません。

15

ローカル変数は常にスタックにあり、モーメント法はすべてのローカル変数がなくなっています。

しかし、内部変数オブジェクトは、メソッドが終了してもヒープになっている可能性があります(インスタンス変数が参照を保持しているとします)。その場合、それらをマークしない限り、ローカル変数にはアクセスできません最終的に

7

これは、ローカルクラスのインスタンスがまだ存在している間に関数呼び出し後にローカル変数が破棄される可能性があるため、関数内の内部クラスが実際にローカル変数をコピーするからです。ローカル変数の2つのコピーが常に同じ値になるようにするには、変数をfinalとして宣言する必要があります。

0

最終的な変数の使用は、最終変数が常に初期化されることを保証します。 初期化せずにローカル変数を使用しようとするとエラーになります。 finalを使用すると、使用されているローカル変数が初期化されている内部クラスが保証されます。

関連する問題