【问题标题】:variable r might not have been initialized变量 r 可能尚未初始化
【发布时间】:2013-11-24 17:35:33
【问题描述】:

有一个非常简单的程序:

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 如何引用指向它的变量?

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

【问题讨论】:

    标签: java final


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      在这种情况下,您的new Runnabler 之前创建,因为操作顺序,赋值运算符右侧的所有内容都在赋值之前执行。这意味着声明 Runnable 时 r 不在作用域内,因此它不知道 run 方法中的内容。

      【讨论】:

        【解决方案3】:

        回答你的第二个问题:

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

        应该可以。

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

        对于你的小例子,将 final Runnable r 移到 main 方法之外并说:

        new A().r.run();
        

        【讨论】:

          【解决方案4】:

          工作代码是:

          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();
              }
          }
          

          所以可以使用辅助对象“unfinal”一个变量。

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

          【讨论】:

            【解决方案5】:
            public class A {
                private static Runnable r; 
                public static void main(String[] p) {
                    r = new Runnable() {
                        public void run() {
                            System.out.println(r);
                        }
                    };
                }
            }
            

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

            【讨论】:

              【解决方案6】:

              只需在 Runnable 中使用 "this" 代替 "r" ))) 就可以了。那么就不需要添加“外层”Runnable了。

              【讨论】:

                【解决方案7】:

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

                    final Runnable r = new Runnable() {
                        public void run() {
                            System.out.println(this); // Avoid compilation error by using this
                        }
                    };
                

                【讨论】:

                  猜你喜欢
                  • 2012-03-25
                  • 2015-07-04
                  • 1970-01-01
                  • 2016-05-14
                  相关资源
                  最近更新 更多