Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Lambda只能与功能接口一起使用?_Java_Lambda_Java 8_Functional Interface - Fatal编程技术网

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

Java Lambda只能与功能接口一起使用?,java,lambda,java-8,functional-interface,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(LambdaConflic

我这样做:

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);
}
公共类LambdaConflict
{
公共静态void main(字符串参数[]){
//*
System.out.println(LambdaConflict.get(
(str)->“你好,世界!!是我干的?”
));
/*/
System.out.println(LambdaConflict.get)(新的Intf(){
@重写公共字符串get1(字符串str){
通过get1+str返回“helloworld!!”;
}
}));
/*****/
}
公共静态字符串get(Intf i,boolean b){
返回i.get1(“从1”);
}
}
接口Intf
{
公共T get1(T arg1);
公共T get2(T arg1);
}
然后得到这个例外:

不兼容类型:Intf不是功能接口 在接口Intf中找到多个非重写抽象方法 注:部分信息已被简化;使用-Xdiags:verbose重新编译以获取 满输出 1错误

有没有什么条件我不能用lambda来代替匿名类?

没有。没有办法“克服”这个问题。函数接口必须只有一个抽象方法。您的界面有两个:

interface Intf<T> {
    public T get1(T arg1);
    public T get2(T arg1);
}
接口Intf{
公共T get1(T arg1);
公共T get2(T arg1);
}
注意:您不需要像注释中提到的那样对接口进行注释。但是,如果接口不是有效的功能接口,则可以使用
@functionalterface
注释获取编译时错误。因此,它为您的代码带来了更多的安全性

有关更多信息,请参见,例如,思考一下:

  • 编译器如何知道是否要重写
    get1
    get2

  • 如果只覆盖
    get1
    ,那么
    get2
    的实现是什么?即使您注释掉的代码也无法工作,因为您没有实现
    get2


这种限制是有原因的。

正如@Thomas Uhrig所述,功能接口只能有一种方法

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

@FunctionalInterface
interface Intf<T>
{
    public T get1(T arg1);
}
@functioninterface
接口Intf
{
公共T get1(T arg1);
}

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

根据Lambda规范第A部分:功能接口中的说明:

函数接口是只有一个抽象的接口 方法(对象的方法除外),因此表示 单功能合同。(在某些情况下,这种“单一”方法可能会 采用多个抽象方法的形式,并具有覆盖等价项 从超级接口继承的签名;在本例中,继承的 方法逻辑上表示单个方法。)


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

克服它是什么意思?您理解错误吗?1)功能接口必须只有一个方法。2) 它们必须注释为@functional接口功能接口也称为SAM类型(单一抽象方法类型)。因此,在函数接口中只能有一个抽象方法。@RichardTingle:我认为第2点是无效的。它们可以被注释,但不是必需的。@RichardTingle:注释的要点。这难道不会使像
Runnable
这样的现有接口不起作用吗?感谢您提供有关
@FunctionalInterface
的提示!我忘了它有特殊的性质。另外,我发现从Oracle升级到最新的JDK8补丁也有助于改进错误消息。JDK8的旧版本有时可能允许编译上述代码,但在运行时会出现
java.lang.AbstractMethodError
。较新版本将在编译时拒绝。