Java 如何引导lambda表达式在类中执行特定方法

Java 如何引导lambda表达式在类中执行特定方法,java,lambda,Java,Lambda,我有一个runner类,它在重载方法中接受Runnable或Callables class MyController { public void run(Runnable command) { } public void run(Callable command) { } } 其他需要执行run方法的类 controllerInstance.run(() -> {...}); 基于lambda表达式的代码如何决定调用run(可运行)或run(可调用)?是否有办法更改此

我有一个runner类,它在重载方法中接受Runnable或Callables

class MyController {
  public void run(Runnable command) {
  }

  public void run(Callable command) {
  }
}
其他需要执行run方法的类

controllerInstance.run(() -> {...});

基于lambda表达式的代码如何决定调用run(可运行)或run(可调用)?是否有办法更改此默认行为?

是方法签名决定了您需要哪种类型的lambda。 因此,当返回
void
时,lambda方法与
Runnable
接口匹配。 当返回一个对象时,lambda方法与
可调用接口匹配

import java.util.concurrent.Callable;

class MyController {
  public void run(Runnable command) {
    System.out.println("Runnable");

  }

  public void run(Callable command) {
    System.out.println("Callable");
  }

  public static void main(String [] args) {
    MyController myController = new MyController();

    myController.run(() -> { return "String"; }  );
    myController.run(() -> {});
  }
}
这将返回:

Callable
Runnable

方法签名决定了您需要哪种类型的lambda。 因此,当返回
void
时,lambda方法与
Runnable
接口匹配。 当返回一个对象时,lambda方法与
可调用接口匹配

import java.util.concurrent.Callable;

class MyController {
  public void run(Runnable command) {
    System.out.println("Runnable");

  }

  public void run(Callable command) {
    System.out.println("Callable");
  }

  public static void main(String [] args) {
    MyController myController = new MyController();

    myController.run(() -> { return "String"; }  );
    myController.run(() -> {});
  }
}
这将返回:

Callable
Runnable

您可以使用转换表达式“标记”lambda,这将指示它应该实现哪些接口。例如:

controllerInstance.run((Runnable) () -> {...});

只需注意,
Callable
实际上有一个返回值,而
Runnable
没有返回值,方法解析会考虑该值。我发现只要lambda主体的块或表达式返回一个值,就会使用
Callable
重载。如果调用确实不明确,则会出现错误,可以使用显式强制转换。

可以使用强制转换表达式“标记”lambda,这将指示它应该实现哪些接口。例如:

controllerInstance.run((Runnable) () -> {...});

只需注意,
Callable
实际上有一个返回值,而
Runnable
没有返回值,方法解析会考虑该值。我发现只要lambda主体的块或表达式返回一个值,就会使用
Callable
重载。如果调用确实不明确,则会出现错误并可以使用显式强制转换。

假设您引用的是
java.lang.Runnable
java.util.concurrent.Callable
,如果您返回值,它将匹配
Callable
,如果它不返回值,它将匹配
Runnable
,因此不需要额外的资格认证

controllerInstance.run(() -> { /*no return*/ }); // calls run(Runnable command)
controllerInstance.run(() -> { return null; });  // calls run(Callable command)
但是,如果需要的话,你可以通过铸造来强制发行

controllerInstance.run((Runnable) () -> { /*no return*/ }); // calls run(Runnable command)
controllerInstance.run((Callable) () -> { return null; });  // calls run(Callable command)

假设您引用的是
java.lang.Runnable
java.util.concurrent.Callable
,如果返回值,它将匹配
Callable
,如果不返回值,它将匹配
Runnable
,因此不需要额外的限定

controllerInstance.run(() -> { /*no return*/ }); // calls run(Runnable command)
controllerInstance.run(() -> { return null; });  // calls run(Callable command)
但是,如果需要的话,你可以通过铸造来强制发行

controllerInstance.run((Runnable) () -> { /*no return*/ }); // calls run(Runnable command)
controllerInstance.run((Callable) () -> { return null; });  // calls run(Callable command)

所以你对“如何引导lambda”的回答是不使用lambda?那么你对“如何引导lambda”的回答是不使用lambda?我建议通过重命名第二个方法
call()
来明确它。有一些方法可以让它与命名的方法一起工作(如下面的答案所示),但它们都会导致代码不那么优雅。我建议通过重命名第二个方法
call()
,使其显式化。有一些方法可以让它与命名的方法一起工作(如下面的答案所示),但它们都会导致代码不那么优雅。