在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 = 2; }).start(); } public static class Node { public int a = 1; }}在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 = 1; }}這時候就會報錯,因為我們嘗試修改node的值(引用),所以就不是有效final了。
新聞熱點
疑難解答