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
Lambda can only be used with functional 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 @FunctionalInterface
annotation 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
get1
orget2
?If you only override
get1
, what will beget2
's implementation? Even the code you commented out won't work because you don't implementget2
...
编译器如何知道您是否要覆盖
get1
或get2
?如果您只覆盖
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.
因此,您需要的是为您的方法之一提供默认实现,或者将您的方法之一放在不同的接口中。