在Java8之前,我們在匿名内部類或者局部内部類中使用局部變量都需要将局部變量聲明為final,這是因為java底層給我們做了一些小動作,匿名内部類表面上沒有構造函數,其實是有的,底層直接将局部變量通過構造函數傳給内部類,局部變量在生命周期結束後就會被銷毀,而匿名内部類的生命周期一般來說都比局部變量長,那麼假如我們可以修改這個變量,就會出現内外不一緻的現象(這裡的修改指的是改變引用,而不是改變變量的内容),因為外面的局部變量是不會因為内部的引用改變而改變的,是以強制要求聲明為final。
但是在Java8中,出現了Effectively final,意思就是,假如這個局部變量我們在使用過程中都不會出現改變引用的情況,那麼我們不需要加final,預設是final,如下代碼
public class Main {
static volatile boolean flag = true;
public static void main(String[] args) {
Node node = new Node();
new Thread(() -> {
node.a = ;
}).start();
}
public static class Node {
public int a = ;
}
}
在Java8編譯中編譯是不會出錯的,然後我們修改一下代碼
public class Main {
static volatile boolean flag = true;
public static void main(String[] args) {
Node node = new Node();
new Thread(() -> {
node = new Node();
}).start();
}
public static class Node {
public int a = ;
}
}
這時候就會報錯,因為我們嘗試修改node的值(引用),是以就不是有效final了。