2016-07-03 16 views
-1

2つのコードバンチを表示します。ここ 内部クラスでローカル変数を変更できないのはなぜですか?

public class A { 

     int globalVariable; 


     public void foo() { 
      globalVariable++; 
      class B { 
       void foo() { 
        System.out.println(globalVariable); 
       } 
      } 

      B b = new B(); 
      b.foo(); 
     } 

     public static void main(String[] args) { 
      A a = new A(); 
      a.foo(); 
     } 
    } 

iは、一つのグローバル変数を宣言し、その値を変更し、1つの内部クラスを宣言し、うまく動作し、今

を印刷します。このclass.Thisコードのインスタンスを作成しましたこのコードをチェックアウト:

 public class A { 

      public void foo() { 
       int localVariable; 
       localVariable++; 
       class B { 
        void foo() { 
         System.out.println(localVariable); 
        } 
       } 

       B b = new B(); 
       b.foo(); 
      } 

      public static void main(String[] args) { 
       A a = new A(); 
       a.foo(); 
      } 
     } 

ここで変数はグローバルではなくローカルです。ここでは、localVariableはfinalまたは実質的にfinalでなければならないという例外があります。私はグーグルでこれがなぜキャプチャされてclass.Whenに渡されたのか理解しています変化し、混乱を招く。 私は2つの質問があります:

それはいくつかの混乱を引き起こす1.ifをして

2.itそれは程度である私たちは、グローバル変数にこの例外を取得しない理由を宣言 後にそれを変更しないする必要がローカル変数の値が変わるので、クラスインスタンス宣言後にこの値を変更した場合にのみ、この例外を取得する必要があります。それはありませんか?

+0

私は重複が彼の2番目の質問に答えるとは思わないので、再度開く投票。 – ajb

+0

彼は組み合わせの質問ではなく、1つの投稿につき1つの質問 –

答えて

1

1)私はあなたの最初の質問にはWhy a non-final "local" variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?と答えていると思います。 (質問は以前はその問題の重複としてマークされていました)一般的に、変数を変更できないというルールは、インスタンスフィールドや配列要素には適用されません。これらの変数によって参照されるオブジェクトの一部です。したがって、これは合法である:

 public void foo() { 
      int[] localVariable = new int[1]; 
      localVariable[0]++; 
      class B { 
       void foo() { 
        System.out.println(localVariable[0]); 
       } 
      } 

      B b = new B(); 
      b.foo(); 
     } 

2)あなたはそれに値を割り当てた、そしてそれは明確な割り当て」についてのルールを破る前にlocalVariableをインクリメントしているので、あなたの2番目のコードスニペットは、とにかく成功することはできません" Javaが、内部クラスが宣言された後に変更されない変数を使用させない理由については、わかりません。しかし、Java 7以前では、ローカル変数(またはパラメータ)を内部クラスで使用するためにfinalと宣言しなければならないというルールがありました。 Java 8では、これはリラックスしていました。変数finalは、が有効な最終である限り、宣言する必要はありませんでした。しかし、私はルールが効果的に最終的には、コンパイラは、finalと宣言されている可能性があるかどうかを判断すると考えています。この場合に、それができない、これは違法ですので、:理論的には

 public void foo() { 
      final int localVariable = 3; 
      localVariable++; 
     } 

、Javaの設計者は、コンパイラは変数が特定のポイントの後に変更することができるかどうかを判断するためにルールを追加している可能性があります。しかし、それはより複雑にされているだろう、それはあまり得ていないだろう、あなたはまだ

 public void foo() { 
      int localVariable = 3; 
      localVariable++; 
      final int finalLocalVariable = localVariable; 
      class B { 
       void foo() { 
        System.out.println(finalLocalVariable); 
       } 
      } 
     } 

は、いくつかの他の変数のコピーを保持するためにfinal変数を宣言すると言うことができますので、内部クラスを使用するときにかなり一般的なイディオムであります少なくとも私が見たものから。

関連する問題