1.内部类如果出现在外部类的非方法里, 内部类可安全的访问类中所有变量。
2.内部类如果出现在外部类的某方法A里(java语法规定只可能是匿名内部类), 那么需要解决一个问题: A方法执行完毕就弹栈了, 局部变量不存在了, 匿名内部类在访问此A方法参数或者A方法局部变量的时候, 该如何做? 这个问题即 内部类的实例(对中的地址值)的生命周期有可能超过局部变量的生命周期(栈中的变量)(此场景即所谓的闭包,在javascript等很多语言中都有)。典型的是回调函数的场景: A方法直接把含有匿名函数的对象返回给外界, 这时候外界可以调用匿名函数, 但是A函数栈桢弹栈了, 也就是匿名函数依赖的局部变量销毁了
何解?
Java解决方法是将局部变量复制一份到内部类(也就是在内名类维护一个构造方法和几个成员变量来对应依赖的外部方法中的局部变量),这样方法执行完后匿名内部类里仍可使用该变量。但是复制就意味着要处理数据同步问题, 比如重新赋值了怎么办
何解?
- 真同步? 虚拟机累啊, 需要侦测变化, 通知再同步, 困难且麻烦
- 地址值不可变(大家指向同一片内存地址, 就算你改东西我也看得到, 只要你不改地址值就行)或者值不变不就行了, 就不用同步了. java final可以做到, 所以java8以前强制final, java8以后, 编译器会贴心的给你补final, 补完不报错, 也就是你没二次赋值, 这就是所谓的effictively final, 补完如果报错, 对不起, 请你不要二次赋值
lambda就是某种匿名内部类的语法糖