【发布时间】:2014-07-01 11:42:58
【问题描述】:
以下类包含一个成员变量runnable,它使用匿名内部类的实例进行初始化。内部类引用相同的成员:
class Example {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(runnable);
}
};
}
只要在分配成员之前不执行方法并且 JLS 允许这样的引用,这不是问题。
成员变量的声明理论上可以转换成这样的 lambda 表达式:
Runnable runnable = () -> System.out.println(runnable);
据我了解,这在功能上等同于前面的示例,但被javac 1.8.0_05 拒绝并显示以下错误消息:
Error:(2, 54) java: self-reference in initializer
虽然该声明是正确的,但我不明白为什么不允许这样做。这是故意不允许的,可能是因为 lambda 表达式被编译为不同的字节码,如果允许的话会导致问题?或者只是因为这些引用在匿名内部类中使用时已经存在问题而被禁止?还是 JLS 的作者无意中不允许这样做?还是javac 中的错误?
【问题讨论】:
-
在 Eclipse 中,这有效:
Runnable runnable = () -> System.out.println(this.runnable);如果没有添加this限定符,它只会失败。