Lambda只能用于功能界面吗?

时间:2014-05-15 15:12:34

标签: java lambda java-8 functional-interface

我这样做了:

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重新编译:获取详细信息       全输出       1错误

是否有任何条件我无法使用lambda替换匿名类?

4 个答案:

答案 0 :(得分:19)

没有。没有办法克服&#34;这个。功能接口必须只有一个抽象方法。你的界面有两个:

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

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

有关详细信息,请参阅http://java.dzone.com/articles/introduction-functional-1

答案 1 :(得分:7)

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

根据JSR-335: Lambda Expressions for the Java Programming Language,在Lambda规范,A部分:功能接口部分中说:

  

功能界面是一个只有一个抽象的界面   方法(除了Object的方法),从而代表一个   单一功能合同。 (在某些情况下,这种“单一”方法可能   采用覆盖等价的多个抽象方法的形式   从超接口继承的签名;在这种情况下,继承   方法在逻辑上代表一种方法。)

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

答案 2 :(得分:2)

想一想:

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

  • 如果您只覆盖get1get2的实施方式是什么?即使您注释掉的代码也不会起作用,因为您没有实施get2 ...

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

答案 3 :(得分:1)

如@ Thomas-Uhrig所述,功能界面只能有一种方法

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

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