最近有一個疑惑:爲何局部內部類中訪問同一方法中的變量,該變量必定要是final修飾的
首先,咱們看一個局部內部類的例子:
class OutClass {
private int temp = 11;
public void outTest(final int x) {
class InClass {
public void innerTest() {
System.out.println(x);
System.out.println(temp);
}
}
new InClass().innerTest();
}
}
這裏有一個外部類OuterClass和一個內部類InClass,內部類訪問了外部類的一個方法中的一個局部變量x,在這裏,x必須是final的,不然會報錯:
Cannot refer to a non-final variable x inside an inner class defined in a different method
下面來分析下這個問題:
追究其根本緣由就是做用域中變量的生命週期致使的;
首先須要知道的一點是:內部類和外部類是處於同一個級別的,內部類不會由於定義在方法中就會隨着方法的執行完畢就被銷燬.
這裏就會產生問題:當外部類的方法結束時,局部變量就會被銷燬了,可是內部類對象可能還存在(只有沒有人再引用它時,纔會死亡)。這裏就出現了一個矛盾:內部類對象訪問了一個不存在的變量。爲了解決這個問題,就將局部變量複製了一份做爲內部類的成員變量,這樣當局部變量死亡後,內部類仍能夠訪問它,實際訪問的是局部變量的」copy」。這樣就好像延長了局部變量的生命週期。
問題又出現了:將局部變量複製爲內部類的成員變量時,必須保證這兩個變量是同樣的,也就是若是咱們在內部類中修改了成員變量,方法中的局部變量也得跟着改變,怎麼解決問題呢?
就將局部變量設置爲final,對它初始化後,我就不讓你再去修改這個變量,就保證了內部類的成員變量和方法的局部變量的一致性。這實際上也是一種妥協。
若變量是final時:
如果基本類型,其值是不能改變的,就保證了copy與原始的局部變量的值是同樣的;
如果引用類型,其引用是不能改變的,保證了copy與原始的變量引用的是同一個對象。
這就使得局部變量與內部類內創建的拷貝保持一致。