Java如何知道在使用lambda表达式时应该覆盖哪个方法

时间:2016-08-13 06:28:15

标签: java lambda java-8

使用JAVA8,内部类可以用lambda表达式替换。

Comparator c = (a, b) -> Integer.compare(a.length(), b.length());

Runnable java8Runner = () ->{System.out.println("I am running");};

jvm如何知道,这个lambda应该覆盖正确的方法?在上面的示例中,它们是run()compare()

2 个答案:

答案 0 :(得分:7)

通过单方法接口促进了这一点。这些接口中只有一个(抽象)方法。如果存在歧义,则不能使用速记lambda语法。

您可以使用@FunctionalInterface注释让编译器对接口强制执行此操作(但是没有必要,即使没有它,也可以在lambdas中使用该接口)。

答案 1 :(得分:5)

Thilo是对的。

然而,术语

  

单的方法的接口

不是更合适,因为功能界面可能有多种方法:可能有多种默认方法,但只有一种抽象方法 例如,它是一个有效的功能接口:

@FunctionalInterface
public interface MyInterface {

    Integer getResult();
    default boolean isNoResult(){
       return getResult()==null;
    }
}

表达式lambda只能在功能接口的上下文中使用。 功能接口是指定一个和单个抽象方法的Java接口。 在您的示例中,Comparator和Runnable只有一个抽象方法。 更多详情:https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html

  

jvm如何知道,这个lambda应该覆盖正确的方法?在上面   例子,它们是run()和compare()。

如果你使用一个没有功能接口的lambda表达式,编译将会出错:编译器确实会在显式消息中抱怨它:
此表达式的目标类型必须是功能接口

因此,即使它不是强制性的,如果您创建一个目标是功能接口的接口,最好使用注释@FunctionalInterface声明它以强制编译器检查它是否为有效的功能接口:一个和一个抽象方法。这样,当您的界面是有效的功能界面时,您现在就会知道。
这就是Java 8中JDK类的原因。