2016-07-03 2 views
-1

Я покажу вам две кучки кода.Почему локальная переменная не может быть изменена во внутреннем классе?

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(); 
     } 
    } 

здесь я объявил одну глобальную переменную, изменила свое значение, заявил один внутренний класс и создал экземпляр этого 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(); 
      } 
     } 

Я сделал все шаги по первому коду e xcept здесь переменная не является глобальной, а local.Here я получаю исключение, которое говорит, что localVariable должно быть окончательным или эффективно final.I googled и понял, что именно поэтому значение получает захвачен и передается классу. Когда мы изменили его класс не знает о это меняется, и это вызывает смущение. у меня есть 2 вопроса:

1.Если это вызвать некоторые запутанным, и мы должны не изменить его после объявления почему мы не получим это исключение на глобальную переменную

2.it речь идет о значение локальной переменной меняется, поэтому мы должны получить это исключение, только если мы изменим это значение после объявления экземпляра класса. Не так ли?

+0

Голосование для повторного открытия, поскольку я не думаю, что дубликат отвечает на его второй вопрос. – ajb

+0

У него не должно быть вопросов, связанных с комбинацией, –

ответ

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, прежде чем вы присвоили ей значение, и что нарушает правила о «определенном присваивании ». Что касается того, почему 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 переменных для хранения копии какого-либо других переменным является довольно распространенными идиомами при использовании внутренних классов , по крайней мере, из того, что я видел.

Смежные вопросы