“嗨,阿米戈!這裡有一些更多的信息給你。”
“我已經告訴過你了,編譯器實際上把所有的匿名類都轉換成了普通的內部類。”
“是的。我什至記得他們的名字都是數字:1、2、3,等等。”
“完全正確。但這裡還有另一個細微差別。”
“如果一個類在方法內部聲明並使用它的任何變量,那麼對這些變量的引用將被添加到生成的類中。你自己看看。”
“我們從這個開始:”
編譯前:
class Car
{
public ArrayList createPoliceCars(int count)
{
ArrayList result = new ArrayList();
for(int i = 0; i < count; i++)
{
final int number = i;
result.add(new Car()
{
public String toString()
{
return ""+number;
}
});
}
return result;
}
}
“編譯器生成了這個:
編譯後:
class Car
{
public ArrayList createPoliceCars(int count)
{
ArrayList result = new ArrayList();
for(int i = 0; i < count; i++)
{
final int number = i;
result.add(new Anonymous2 (number));
}
return result;
}
class Anonymous2
{
final int number;
Anonymous2(int number)
{
this.number = number;
}
public String toString()
{
return ""+ number;
}
}
}
“你明白了嗎?內部類不能改變方法的局部變量,因為當內部類的代碼被執行時,我們可能會完全退出方法。”
“現在是第二點。toString() 方法使用傳遞的變量。要實現這一點,有必要:”
A)將其保存在生成的類中
B)將其添加到構造函數中。
“明白了。在方法內部聲明的類總是使用變量的副本。”
“確切地!”
“那麼為什麼變量必須是最終的就很有意義了。為什麼他們不能改變。如果你實際上是在使用副本而不是原件,用戶將不明白為什麼他不能改變變量的值,這意味著我們只需要禁止他改變它們。”
“是的,將變量聲明為 final 似乎是一個很小的代價,以換取編譯器為您生成一個類,將其傳遞給方法,並保存您要使用的所有方法變量。”
“我同意,匿名本地班還是超級爽的。”
“如果我在一個方法中聲明一個本地類,並在其中使用該方法的變量,編譯器是否也會將它們添加到該類中?”
“是的,它會將它們添加到類及其構造函數中。”
“我也這麼想。”
GO TO FULL VERSION