關于final修飾符的一些小坑
今天在測試JUC包的CyclicBarrier方法的時候,遇到一個關于jfinal的問題
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("運作到最後");
});
for (int i = 0; i < 7; i++) {
final int tmp = i;
new Thread(()->{
//這裡引用tmp 需要tmp是final修飾的 在JDK1.8之後,不使用final也可以,但tmp的值不能改變,因為JDK1.8在編譯的時候做了處理
System.out.println(tmp);
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
這裡的tmp如果需要在匿名内部類中使用,那麼需要final關鍵字修飾,在JDK1.8中進行了優化處理,可以不加,但是不允許值發生改變
在匿名内部類中通路局部變量,那麼這個局部變量必須用final修飾
為什麼需要用final修飾呢?
- 因為為了保護資料的一緻性,對于基本類型如(int)來說的就是值的一緻性,對于引用變量來說的,就是引用位址的一緻性
- 如果不使用final進行修飾,那麼原先的局部變量可以發生變化,那麼匿名内部類在引用的時候就會出錯
- 因為最開始建立匿名内部類後,值是在匿名内部類的構造器中進行指派傳入的,是以後續代碼的修改,會導緻程式最終結果不一緻