Java8中的Lambda表达式

Ash*_*shu 8 java lambda java-8

import java.util.concurrent.Callable;

public class AdvancedLambda {

    static void invoke(Runnable r){
        r.run();
    }

    static Object invoke(Callable c) throws Exception {
        return c.call();
    }

    public static void main(String[] args) throws Exception {

        String s = (String) invoke(() -> true);
        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我理解这个吗?我的印象是,只有当我们实现一个接口并覆盖其方法(用Lambda表达式替换Anonymous类)时,我们才能在Java 8中使用lamba表达式.

在哪种情况下会invoke(Runnable r)调用该方法?

Tun*_*aki 8

在以下行中

String s = (String) invoke(() -> true);
Run Code Online (Sandbox Code Playgroud)

它实际上invoke(Callable)是被调用的.原因是:

  • () -> true 是一个lambda表达式,它具有零形式参数并返回结果.
  • 这样的签名(零参数,单结果)是与功能方法兼容call()的的Callable接口.请注意,接口不需要具有@FunctionalInterface注释,它只需要一个抽象方法.

如果要调用invoke(Runnable),则需要创建一个与函数方法兼容的lambda,该函数方法接受零参数并且不返回任何结果(即符合签名run()).像这样的东西:

invoke(() -> System.out.println("foo"));
Run Code Online (Sandbox Code Playgroud)

哪个只是foo在跑步时打印.


Era*_*ran 8

lambda表达式为功能接口提供实现.这就是您的代码段所做的事情.

您的调用invoke传递一个lambda表达式,其中没有返回值的参数(boolean在您的情况下为a).因此它匹配Object invoke(Callable c),而不是void invoke(Runnable r)(因为Callablecall方法有一个返回值,而Runnablerun方法不返回任何东西).

invoke(() -> {System.out.println("something");});
Run Code Online (Sandbox Code Playgroud)

将调用void invoke(Runnable r),因为在这种情况下lambda表达式没有返回类型.


Mic*_*l M 7

只有当我们实现一个接口并覆盖其方法时

这或多或少都是你在这里所做的.没有方法小号,但只有一个方法:call().这() -> true部分是你的实现Callable#call().

换句话说,这一行:

String s = (String) invoke(() -> true);
Run Code Online (Sandbox Code Playgroud)

将完全等同于这一个:

String s = (String) invoke(new Callable() {
        @Override
        public Object call() throws Exception {
            return true;
        }
    });    
Run Code Online (Sandbox Code Playgroud)