一、闭包

  1. 一个依赖于自由变量的函数
  2. 处在含有这些自由变量的一个外围环境
  3. 这个函数能够访问外围环境里的自由变量

**内部类:**通过包含一个指向外部类的引用,做到自由访问外部环境类的所有字段,变相把环境中的自由变量封装到函数里,形成一个闭包。

java 匿名内部类如何引用外部类实例对象 java匿名内部类final_匿名内部类

二、匿名内部类实现

匿名内部类通过capture-by-value实现的,就是会将局部变量拷贝一份到匿名类中,在匿名类中要update只能update拷贝对象,无法影响原对象,这就会导致数据不一致,所以Java直接规定匿名内部类引用的局部变量必须使用final修饰,java 8 之后不需要显式使用final修饰,但是也要求不能重新赋值。

**tip1:**Java只是不允许改变被匿名内部类引用的变量,并没有限制这些变量所指向的对象的状态能不能变。

**tip2:**局部类和匿名内部类的实现方式相似。

三、匿名内部类、局部类为什么要拷贝变量

这是作用域的原因,在外部类method执行完成后,局部变量value就失效了,而在匿名内部类局部类产生的对象还存在obj的引用,这样对象就访问了一个不存在的变量,是不允许的。iner还存在,在外面和后续调用该局部变量时,这个局部变量可能已经失效了。但为什么加上final就可以保证能访问呢?这里Java采用了一种copy local variable的方法实现,定义为final的变量,会拷贝一份存到局部内部类中,后续使用持续维护这个对象在生命周期内,所以可以继续访问。

tip:

1、为什么普通内部类不需要呢?

原因:普通内部类有this指针指向外部类实例,只要普通内部类没被回收,外部类实例就不会被回收,就不存在作用域的问题。