Java Scope и Lifetime (внутренние классы) - PullRequest
0 голосов
/ 06 февраля 2012

Мне нужно объяснить, почему следующий код не может быть скомпилирован (с точки зрения области действия и времени жизни):

class ClassInMethod
{
   public static void main(String[] args)
   {
      int local = 1;

      class Inner
      {
         public void method()
         {
             System.out.println(local);
         }
      }
   }
}

Я думаю это потому что: Любая локальная переменная, используемая, но не объявленная во внутреннем классе, должна быть объявлена ​​как «конечная». Таким образом, в этом примере «local» должен быть объявлен как final, поскольку его область действия и время жизни заканчиваются в методе main (поэтому его необходимо изменить на: final int local = 1;).

Есть еще предложения?

Ответы [ 3 ]

2 голосов
/ 06 февраля 2012

См. http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ для объяснения того, как компилятор использует трюк final, чтобы обойти проблемы с внутренними классами (то есть проблемы объема и времени жизни).

1 голос
/ 06 февраля 2012

Причина, по которой вы должны сделать локальные переменные final, заключается в том, что Java копирует их значения в экземпляр внутреннего класса. За кулисами происходит то, что компилятор генерирует байт-код, который (примерно) соответствует этому:

class ClassInMethod {
    public static void main(String[] args) {
        int local = 1;

        // this happens when you do: new Inner()
        ClassInMethod_main_Inner inner = new ClassInMethod_main_Inner();
        inner.local = local;
    }
}

// the inner class
class ClassInMethod_main_Inner {
    int local;

    public void method() {
        System.out.println(local);
    }
}

Если local не было final, и вы можете изменить его значение между моментом создания экземпляра Inner и вызовом method(), при вызове method() будет использоваться старое значение local. Это, вероятно, будет неправильным поведением. final обязана сделать интуитивно понятным поведение внутренних классов.

(Существуют языки, которые не имеют этого ограничения, но требуют явной поддержки со стороны компилятора и среды выполнения. Разработчики Java до сих пор не решили посвятить свои усилия его реализации.)

1 голос
/ 06 февраля 2012

Просто попробуйте скомпилировать.Компилятор выводит:

ClassInMethod.java:11: local variable local is accessed from within inner class; needs to be declared final
    System.out.println(local);
                       ^
1 error
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...