作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在 Java 中,匿名内部类可以引用其本地范围内的变量:
public class A {
public void method() {
final int i = 0;
doStuff(new Action() {
public void doAction() {
Console.printf(i); // or whatever
}
});
}
}
我的问题是这实际上是如何实现的? i
是如何到达匿名内部 doAction
实现的,为什么它必须是 final
?
最佳答案
局部变量(显然)不会在不同的方法之间共享,例如上面的 method()
和 doAction()
。但由于它是最终的,在这种情况下不会发生任何“坏事”,所以语言仍然允许它。然而,编译器需要对这种情况做一些聪明的事情。让我们看看 javac
产生了什么:
$ javap -v "A\$1" # A$1 is the anonymous Action-class.
...
final int val$i; // A field to store the i-value in.
final A this$0; // A reference to the "enclosing" A-object.
A$1(A, int); // created constructor of the anonymous class
Code:
Stack=2, Locals=3, Args_size=3
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:LA;
5: aload_0
6: iload_2
7: putfield #2; //Field val$i:I
10: aload_0
11: invokespecial #3; //Method java/lang/Object."<init>":()V
14: return
...
public void doAction();
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: getfield #2; //Field val$i:I
7: invokevirtual #5; //Method java/io/PrintStream.println:(I)V
10: return
这其实说明了它
i
变量变成了一个字段,A
对象的引用doAction()
方法中访问。(附注:我必须将变量初始化为 new java.util.Random().nextInt()
以防止它优化掉大量代码。)
类似的讨论在这里
method local innerclasses accessing the local variables of the method
关于java - java如何实现内部类闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2804923/
我是一名优秀的程序员,十分优秀!