Как и все остальные здесь, локальные переменные должны быть конечными для доступа к внутреннему классу.
Вот (в основном), почему это так ... если вы пишете следующий код (длинный ответ, но, внизу, вы можете получить короткую версию: -):
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
foo.bar();
}
}
компилятор переводит это примерно так:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
class $1
implements Foo
{
public void bar()
{
System.out.println(x);
}
}
foo = new $1();
foo.bar();
}
}
, а затем это:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new $1(x);
foo.bar();
}
private static class $1
implements Foo
{
private final int x;
$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
}
и, наконец, вот что:
class Main
{
public static void main(String[] args)
{
final int x;
Main$Foo foo;
x = 42;
foo = new Main$1(x);
foo.bar();
}
}
interface Main$Foo
{
void bar();
}
class Main$1
implements Main$Foo
{
private final int x;
Main$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
Важным является то, где он добавляет конструктор к $ 1.Представьте себе, если бы вы могли сделать это:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
x = 1;
foo.bar();
}
}
Можно ожидать, что foo.bar () выведет 1, но на самом деле выведет 42. Требуя, чтобы локальные переменные были окончательными, эта запутанная ситуация не может возникнуть.