Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Can';无法编译调用自身的可运行的?_Java_Variable Assignment_Runnable - Fatal编程技术网

Java Can';无法编译调用自身的可运行的?

Java Can';无法编译调用自身的可运行的?,java,variable-assignment,runnable,Java,Variable Assignment,Runnable,我试图使一个可运行的调用自身: class A { public void f() { final Runnable r = new Runnable() { public void run() { // do stuff, return if it worked. r.run(); // otherwise try again } }; } } 它将获得以下错误: $ javac A.java A.java:6:

我试图使一个
可运行的
调用自身:

class A {
  public void f() {
    final Runnable r = new Runnable() {
      public void run() {
        // do stuff, return if it worked.
        r.run(); // otherwise try again
      }
    };
  }
}
它将获得以下错误:

$ javac A.java
A.java:6: error: variable r might not have been initialized
        r.run(); // otherwise try again
        ^
1 error
为什么??在
Runnable
的标准库定义中是否有什么特殊之处,它取消了接口实现在使用之前完全定义的保证(例如,它有一些代码在您对其进行实现时运行)

无法编译调用自身的runnable

您可以--只是不要用
r
限定
run()
方法的名称;您可以明确地引用其内部的方法:

class A {
  public void f() {
    final Runnable r = new Runnable() {
      public void run() {
        ...
        run();  // notice that there is no `r.`
      }
    };
  }
}
代码中的问题是,您试图在变量
r
完全初始化之前使用它。这有点像:

int x = x;

这当然是无效的(并产生相同的错误消息)。

这与Runnable无关。相反,由于赋值右侧的表达式发生在赋值之前,因此会产生此编译器错误

在这种情况下,编译器没有一种简单的方法来知道
r
是否是变量表达式实际执行的时间,因此完全禁止访问

每个局部变量(§14.4)和每个空白最终字段(§4.12.4,§8.3.1.2)在访问其值时必须具有明确的赋值

考虑下面的例子,它说明了这个问题,并以与最初发布的示例相同的编译器错误失败

final String r = (new Object() {
    public String toString() {
        // -> error: variable r might not have been initialized
        // (And in this case it is indeed *not* assigned!)
        return "Hello " + r + "!";
    }
}).toString();

对狗的评论的答复:

。。这正是我今天遇到错误时的想法。但是我想不出有什么理由不只是假设在定义接口实现时定义了r

在上面的示例中,显示了一种情况,即变量
r
在分配之前肯定会被访问。同样,如果构造函数调用了一个虚拟方法(比如
run
),那么在分配它之前就可以访问它——但是这种情况在编译单元中无法检测到


这对于匿名类型中的
final
和访问来说是一个更大的问题:Java不会在final变量上创建闭包,而是在创建匿名类型的实例时绑定这些变量的值。这会在访问变量(实际上是访问以前绑定的值)和创建匿名实例之间创建无效的循环关系。

您可以保存此指针并在新的Runnable中调用Run方法:

    Runnable r = new Runnable() {
        @Override public void run() {
            // if condition met and need to run more
            final Runnable that = this;
            executor.execute(new Runnable() { @Override public void run() { that.run(); } });
        }
    };

您的代码示例有什么问题?它看起来应该对我有用。@Dog它不会编译,会导致
错误:变量r可能没有初始化
。当你说“之前发生”时,你是在谈论共享内存上下文中使用的
之前发生
的形式关系吗?是的,它不会编译,但我不明白为什么。不。这里没有并发问题。
v
仅在赋值语句之后出现。这个错误就是因为这个原因而产生的。这种解决方法有一定的帮助,但是如果我在
r
内部调用
r.run()
@Dog,我仍然会遇到同样的错误。你不能调用外部的
run()
从另一个
Runnable
——内部
Runnable
不知道在哪里声明它。你到底想干什么?我不知道我能不能理解你。这如何解释为什么代码不能编译?