匿名 class 如何访问父 class 的参数?
How does an anonymous class access parent class' parameters?
鉴于此 SSCE:
public class AnonymousClassTest {
String param = "initial";
void test() {
Runnable runnalbe = new Runnable() {
@Override
public void run() {
System.out.println(param);
}
};
runnalbe.run();
param = "after";
runnalbe.run();
}
public static void main(String[] args) {
new AnonymousClassTest().test();
}
}
任何人都可以指出 JLS 或任何其他文档中的一部分来解释为什么结果是
initial
after
而不是因为 param
缺少 final
而没有编译,或者只是打印:
initial
initial
我记得在将参数以这种方式传递给匿名 class 时需要 final
,但在 Java 中似乎并非如此 7. 发生了什么变化?
没有任何变化。外部 class 的字段始终可供内部 class 访问。仅当从内部 class.
访问 局部变量 时才需要 final
在 Java8 中,即使是局部变量也不需要声明为 final。它们必须只是有效最终的,即编译器足够聪明,可以检查它们是否从未被重新分配。
打印的内容完全正常,因为内部 class 只是引用了外部 class 实例,并且访问其字段的方式与外部 [=21= 的方法相同] 就可以了。
8.1.3节中定义:
Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing type declaration.
它的工作方式很简单:编译器为您的内部 class 创建构造函数,并将封闭实例的引用传递给该构造函数。每当您的内部 class 引用已解析为封闭 class 成员的变量时,将通过在构造对象时存储的引用进行访问。
不要求class的成员变量必须是final
。该要求仅适用于局部变量,在创建内部 class 的对象时是 "captured"。
鉴于此 SSCE:
public class AnonymousClassTest {
String param = "initial";
void test() {
Runnable runnalbe = new Runnable() {
@Override
public void run() {
System.out.println(param);
}
};
runnalbe.run();
param = "after";
runnalbe.run();
}
public static void main(String[] args) {
new AnonymousClassTest().test();
}
}
任何人都可以指出 JLS 或任何其他文档中的一部分来解释为什么结果是
initial
after
而不是因为 param
缺少 final
而没有编译,或者只是打印:
initial
initial
我记得在将参数以这种方式传递给匿名 class 时需要 final
,但在 Java 中似乎并非如此 7. 发生了什么变化?
没有任何变化。外部 class 的字段始终可供内部 class 访问。仅当从内部 class.
访问 局部变量 时才需要 final在 Java8 中,即使是局部变量也不需要声明为 final。它们必须只是有效最终的,即编译器足够聪明,可以检查它们是否从未被重新分配。
打印的内容完全正常,因为内部 class 只是引用了外部 class 实例,并且访问其字段的方式与外部 [=21= 的方法相同] 就可以了。
8.1.3节中定义:
Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing type declaration.
它的工作方式很简单:编译器为您的内部 class 创建构造函数,并将封闭实例的引用传递给该构造函数。每当您的内部 class 引用已解析为封闭 class 成员的变量时,将通过在构造对象时存储的引用进行访问。
不要求class的成员变量必须是final
。该要求仅适用于局部变量,在创建内部 class 的对象时是 "captured"。