Java Lambda 只能与函数式接口一起使用吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23682243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 00:40:19  来源:igfitidea点击:

Lambda can only be used with functional interface?

javalambdajava-8functional-interface

提问by Valen

I did this:

我这样做了:

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);
}

and get this exception:

并得到这个例外:

incompatible types: Intf is not a functional interface multiple non-overriding abstract methods found in interface Intf Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error

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

Is there any condition that I can't use lambda to replace anonymous class?

有什么条件我不能使用 lambda 来替换匿名类吗?

采纳答案by Thomas Uhrig

No. There is no way to "overcome" this. A functional interface must have only one abstract method. Your interface has two:

不,没有办法“克服”这一点。一个函数式接口必须只有一个抽象方法。你的界面有两个:

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

Note: You don't need to annotate your interface as mentioned in comments. But you can use the @FunctionalInterfaceannotation to get compile time errors if your interface is not a valid functional interface. So it brings you a little bit more security in your code.

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

For more see e.g. http://java.dzone.com/articles/introduction-functional-1

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

回答by Idan Arye

Think about it:

想想看:

  • How should the compiler know if you want to override get1or get2?

  • If you only override get1, what will be get2's implementation? Even the code you commented out won't work because you don't implement get2...

  • 编译器如何知道您是否要覆盖get1get2

  • 如果您只覆盖get1,那么将是什么get2实现?即使您注释掉的代码也不起作用,因为您没有实现get2......

There are reasons for this limitation...

这种限制是有原因的......

回答by DirkyJerky

As stated by @Thomas-Uhrig, Functional Interfaces can only have one method.

正如@Thomas-Uhrig 所说,函数式接口只能有一种方法

A way to fix this, primarily because you never use public T get2(T arg1);, is to change the Intf<T>interface to:

解决此问题的一种方法,主要是因为您从未使用public T get2(T arg1);,是将Intf<T>界面更改为:

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

回答by Edwin Dalorzo

Just for reference and to enrich the answers already given:

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

As per JSR-335: Lambda Expressions for the Java Programming Language, in section Lambda Specification, Part A: Functional Interfaces it says:

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

A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. (In some cases, this "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.)

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

So, what you need is to either provide a default implementation for one of your methods or put one of your methods in a different interface.

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