2014-12-11 3 views
2
class Outer 
{ 
    void m1() 
    { 
     int a=12; 
     class Inner 
     { 
      void show() 
      { 
       System.out.println(a); 
      } 
     } 
     new Inner().show(); 
    } 

} 

Здесь, когда я компилирую этот код, я получаю ошибку, с которой осуществляется локальная переменная a из внутреннего класса; должен быть объявлен окончательным. но здесь «int a» - это локальная переменная, поэтому нам нужно объявить окончательным для доступа во внутреннем классе.Ошибка: локальная переменная a доступна изнутри внутреннего класса; должно быть объявлено окончательным

+0

@duffymo Я думаю, что он хочет знать, почему ** ** это 'final', вместо того, чтобы просто быть роботом и делать то, что компилятор говорит ... – cno

ответ

3

Локальная переменная должна быть объявлена ​​final, если она используется во внутреннем классе. Для локальной переменной, которая будет использоваться в таком внутреннем классе, Java за кулисами берет копию локальной переменной и превращает ее в неявную переменную экземпляра, чтобы внутренний класс мог получить к ней доступ. Поскольку это копия, копия может быть неправильной, если значение изменяется. Поэтому компилятор заставляет вас сделать это final.

Обратите внимание, что в Java 8 это будет скомпилировано, потому что a является «фактически окончательным» - не объявлено final, но никогда не менялось после инициализации.

Section 8.1.3 of the JLS состояние:

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

Section 4.12.4 of the JLS состояние:

A local variable or a method, constructor, lambda, or exception parameter is effectively final if it is not declared final but it never occurs as the left hand operand of an assignment operator (§15.26) or as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).

In addition, a local variable whose declaration lacks an initializer is effectively final if all of the following are true:

  • It is not declared final.

  • Whenever it occurs as the left-hand operand of an assignment operator, it is definitely unassigned and not definitely assigned before the assignment; that is, it is definitely unassigned and not definitely assigned after the right-hand operand of the assignment (§16 (Definite Assignment)).

  • It never occurs as the operand of a prefix or postfix increment or decrement operator.

+0

Спасибо. @ rgettman –

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

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