Java内部类(4):为什么方法传递给匿名内部类或局部内部类的参数必须是final的

xiaoxiao2021-02-28  84

首先举一个匿名内部类的例子:

class Outer{ public Inner getInner(String name){ return new Inner(){ //name = name+" ";编译错误,这里用来示例 public void printf(){ System.out.println(name); } }; } }

1.外部的局部变量传递到内部类中,实际上是将局部变量复制了一份之后,复制品直接作为局部内部类(匿名类也是一种局部内部类)的数据成员,内部类并不直接操作外部的局部变量,而是访问这个复制品(即:这个复制品就代表了局部变量)。因为局部变量的生命周期在方法调用之后就结束了,但内部类的生命周期在方法调用之后还没有结束,只有在内部类引用完全不被使用之后才会由垃圾回收处理。 但是从语义上来看,似乎

当变量是final时,通过将final局部变量”复制”一份,复制品直接作为局部内部中的数据成员.这样:当局部内部类访问局部变量 时,其实真正访问的是这个局部变量的”复制品”(即:这个复制品就代表了那个局部变量) 上面那份代码相当于(实际上更复杂一些,但大致相当于这个原理):

public class Outer{ public Inner getInner(final String name){ return new Outer$1(name); class Outer$1 implements Inner{ Outer$1(String name) { this.name = name; } public void printf(){ System.out.println(this.name); } } } }

如果在内部类中操作name,实际上操作的是nane的复制品,对原有的局部变量并不会产生影响。如果不加final,就会编译成如下样子

public class Outer{ public Inner getInner(final String name){ return new Outer$1(name); class Outer$1 implements Inner{ Outer$1(String name) { this.name = name; this.name = this.name + " "; } public void printf(){ System.out.println(this.name); } } } }

但是从语义语法上来看:

class Outer{ public Inner getInner(String name){ return new Inner(){ name = name+" "; public void printf(){ System.out.println(name); } }; } }

局部变量发生了改变,客户端并不会意识到内部类修改的只是局部变量的复制品。所以为了防止这种语义语法上的不一致,强行规定传递给局部内部类的变量必须是final

转载请注明原文地址: https://www.6miu.com/read-52353.html

最新回复(0)