关于内部类引用外部变量的理解

观察下面代码

  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 }

猜你喜欢

转载自www.cnblogs.com/liangwenhan/p/11318659.html
今日推荐