为什么下面的第一个例子不起作用?
run(R::new);
方法R.run
未被调用。run(new R());
方法R.run
被调用。
这两个示例都是可编译的。
public class ConstructorRefVsNew {
public static void main(String[] args) {
new ConstructorRefVsNew().run(R::new);
System.out.println("-----------------------");
new ConstructorRefVsNew().run(new R());
}
void run(Runnable r) {
r.run();
}
static class R implements Runnable {
R() {
System.out.println("R constructor runs");
}
@Override
public void run() {
System.out.println("R.run runs");
}
}
}
输出是:
R constructor runs
-----------------------
R constructor runs
R.run runs
在第一个例子中,调用了 R
构造函数,它返回 lambda(不是对象):
但那怎么可能编译成功呢?
最佳答案
您的run
方法采用 Runnable
实例,这就解释了为什么 run(new R())
与 R
一起使用实现。
R::new
不等于 new R()
.它可以适合 Supplier<Runnable>
的签名(或类似的功能接口(interface)),但 R::new
不能用作 Runnable
使用您的 R
实现类。
您的 run
的一个版本可以采取的方法R::new
可能看起来像这样(但这会不必要地复杂):
void run(Supplier<Runnable> r) {
r.get().run();
}
Why does it compile?
因为编译器可以生成 Runnable
在构造函数调用之外,这将等效于这个 lambda 表达式版本:
new ConstructorRefVsNew().run(() -> {
new R(); //discarded result, but this is the run() body
});
这同样适用于这些陈述:
Runnable runnable = () -> new R();
new ConstructorRefVsNew().run(runnable);
Runnable runnable2 = R::new;
new ConstructorRefVsNew().run(runnable2);
但是,如您所见, Runnable
使用 R::new
创建只是调用new R()
在其run
方法体。
有效地使用方法引用来执行 R#run
可以使用这样的实例(但在这种情况下,您肯定更愿意直接使用 r
实例):
R r = new R();
new ConstructorRefVsNew().run(r::run);
关于java - Runnable::new 与新的 Runnable(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54072359/