正如其他人在這裏所說的,局部變量必須是最終才能被內部類訪問。
這裏是(基本上)這是爲什麼?如果你寫了下面的代碼(長的答案,但是,在底部,你可以得到短版:-):
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.通過要求局部變量是最終不能出現這種混亂的局面。
太糟糕了,java需要在這裏做決定。編譯器明顯知道局部變量沒有改變,所以不應該要求編碼器確認。如果匿名類寫入局部變量,編譯警告就足夠了。糟糕的壞設計選擇。 – irreputable 2010-07-14 23:24:13
可能的重複[爲什麼只有最後一個變量可以在匿名類中訪問?](http://stackoverflow.com/questions/4732544/why-are-only-final-variables-accessible-in-anonymous-class) – vaxquis 2015-07-01 14:23:45