首先上一段代碼(一言不合就上代碼)
public class AreaOuter {
private int cnt = 1;
public void show() {
// 局部變量,java8開始,如果該變量被内部類引用,java編譯器就會預設給該變量加final修飾。
// 是以,如果該變量需要被内部類引用,雖然可以省略final,但是在實際開發中最好還是加上final。
// 如果沒有被内部類引用,那麼java編譯器就不會做處理。
int ib = 2;
// 局部内部類
final class AreaInner {
private int ia = 1;
public AreaInner() {
System.out.println("局部内部類的構造方法");
}
public void test() {
// 如果用到外部的變量ib,則ib為final修飾的
System.out.println("ib = " + ib);
System.out.println("ia = " + ia);
System.out.println("cnt = " + cnt);
}
}
//調用方法:隻能在方法體内部調用,聲明局部内部類的引用指向局部内部類的對象
AreaInner areaInner = new AreaInner();
areaInner.test();
}
}
再來解釋為什麼
首先給出一個結論:生命周期不一緻。
局部變量ib和内部類AreaInner都是在show方法中聲明的,其生命周期在調用show方法之後就結束了。但是,局部變量ib是優先于局部内部類AreaInner聲明的,是以局部變量ib的生命周期要長一點。在局部内部類AreaInner引用局部變量ib的時候,實際上會将ib的值拷貝一份拿到内部類使用。
這個時候就可能産生一個問題,什麼問題呢?假如我在局部内部類AreaInner引用局部變量ib之後,背着AreaInner把ib的值給改變了,結果AreaInner還在傻乎乎地按照改變之前的值運作程式,最終就會導緻運作結果出現差錯。
是以為了防止這種情況發生,java編譯器就會在局部變量的前面加上final修飾。這樣一來,ib的值改不了,那麼最後局部内部類引用局部變量運作的結果也就不會出現差錯。