观察下面代码
1,如果把第五行的注释打开则编译不通过,因为方法内的变量需要是final变量或者事实上的final变量(effectively final)才可以传入匿名内部类被使用
2,把第五行注释加上之后,用java8可以编译通过,此时变量d是事实上的final变量,jvm可以放心地把该变量复制到内部类中
3,为什么需要把d复制一份到内部类?因为test1方法的生命周期比内部类要短,导致test1执行完之后栈内的变量随着方法栈销毁而销毁,此时内部类还存在
4,第二和第三个方法,内部类也引用了外部的变量,但是c和w都分配在堆区,生命周期不受限制,所以不必要复制到内部类里边
1 public class InnerClassTest { 2 3 void test1() { 4 int d = 2; 5 //d = 3; 6 new Runnable() { 7 @Override 8 public void run() { 9 System.out.println(d); 10 } 11 }; 12 } 13 14 int c = 1; 15 void test2() { 16 c = 2; 17 new Runnable() { 18 @Override 19 public void run() { 20 System.out.println(c); 21 } 22 }; 23 } 24 25 void test3() { 26 W w = new W(); 27 Thread thread = new Thread(new Runnable() { 28 @Override 29 public void run() { 30 w.i = 4; 31 System.out.println(w.i); 32 } 33 }); 34 thread.run(); 35 System.out.println(w.i); 36 } 37 } 38 class W { 39 int i = 2; 40 }
原文地址:https://www.cnblogs.com/liangwenhan/p/11318659.html
时间: 2024-10-01 03:43:21