8

有一个非常简单的程序:

public class A {
    public static void main(String[] p) {
        final Runnable r = new Runnable() {
            public void run() {
                System.out.println(r);
            }
        };
        r.run();
    }
}

这给出了:

$ javac A.java 
A.java:6: variable r might not have been initialized
                System.out.println(r);
                                   ^
1 error
  1. 为什么?
  2. Runnable 如何引用指向它的变量?

(在实际代码中,多了一层(监听器),引用 viathis不起作用)

4

7 回答 7

6

在这种情况下,您可以使用“this”来避免编译错误:

    final Runnable r = new Runnable() {
        public void run() {
            System.out.println(this); // Avoid compilation error by using this
        }
    };
于 2018-02-21T23:15:06.700 回答
5

回答你的第二个问题:

Runnable outer = new Object() {
   public final Runnable r = new Runnable() {
        public void run() {
            System.out.println(r);
        }
    };
}.r;
outer.run();

应该管用。

在这里,编译器看到 r 将通过隐式构造函数进行初始化。

对于您的小示例,将final Runnable rmain 方法移到外部并说:

new A().r.run();
于 2013-11-12T14:25:07.493 回答
2

在这种情况下,您new Runnable是在之前创建r的,由于操作的顺序,赋值运算符右侧的所有内容都在赋值之前执行。这意味着r当你的 Runnable 被声明时它不在范围内,因此它不知道它在run方法内部是什么。

于 2013-11-12T14:13:50.937 回答
1

r您的方法范围内没有变量run(),您试图在其初始化期间"might not have been initialized"打印出一些值......这就是它的原因。

于 2013-11-12T14:12:00.773 回答
1

只需在 Runnable 中使用 "this" 代替 "r" ))) 就可以了。然后你不需要添加“外部”Runnable。

于 2016-04-12T05:45:38.587 回答
0

工作代码是:

public class A {
    public static void main(String[] p) {
        class RunnableHolder { Runnable r; };
        final RunnableHolder r = new RunnableHolder();
        r.r = new Runnable() {
            public void run() {
                System.out.println(r.r);
            }
        };
        r.r.run();
    }
}

因此,可以使用辅助对象“取消最终”变量。

看起来这种构造(一个辅助对象,其字段可以从 Runnable 访问)正是 Java 的设计者试图禁止的。:)

于 2013-11-13T06:57:12.967 回答
0
public class A {
    private static Runnable r; 
    public static void main(String[] p) {
        r = new Runnable() {
            public void run() {
                System.out.println(r);
            }
        };
    }
}

这应该工作!并且运行范围内没有r,因此在匿名实现中找不到它。

于 2014-11-27T12:25:55.217 回答