Lambda 只能与功能接口一起使用?

2022-09-02 09:15:29

我这样做了:

public class LambdaConflict
{
    public static void main(String args[]){
        //*
        System.out.println(LambdaConflict.get(
            (str) -> "Hello World!! By ME?"
        ));
        /*/
        System.out.println(LambdaConflict.get(new Intf<String> (){
            @Override public String get1(String str){
                return "Hello World!! By get1 " + str;
            }
        }));
        /*****/
    }

    public static String get(Intf<String> i, boolean b){
        return i.get1("from 1");
    }
}

interface Intf<T>
{
    public T get1(T arg1);

    public T get2(T arg1);
}

并得到这个例外:

不兼容的类型:Intf不是功能接口 接口 Intf中发现的多个非覆盖抽象方法 注意:一些消息已被简化;使用 -Xdiags:verbose 重新编译以获得完整输出 1 错误

是否有任何条件不能使用 lambda 来替换匿名类?


答案 1

不。没有办法“克服”这一点。功能接口必须只有一个抽象方法。您的界面有两个:

interface Intf<T> {
    public T get1(T arg1);
    public T get2(T arg1);
}

注意:您无需按照评论中提到的方式对界面进行注释。但是,如果您的接口不是有效的功能接口,则可以使用注释来获取编译时错误。因此,它为您的代码带来了更多的安全性。@FunctionalInterface

有关更多信息,请参阅例如 http://java.dzone.com/articles/introduction-functional-1


答案 2

仅供参考并丰富已经给出的答案:

根据JSR-335:Java编程语言的Lambda表达式,在Lambda规范部分,A部分:函数式接口中,它说:

函数接口是只有一个抽象方法(Object 方法除外)的接口,因此表示单个函数协定。(在某些情况下,这种“单个”方法可能采用多个抽象方法的形式,这些抽象方法具有从超接口继承的覆盖等效签名;在这种情况下,继承的方法在逻辑上表示单个方法。

因此,您需要的是为其中一个方法提供默认实现,或者将其中一个方法放在不同的接口中。


推荐