我理解Java8 lambda表达式的语法,但为什么下面的代码在没有x的特定类型声明的情况下工作?为什么" baz"正在印刷?
public class LambdaExpressions {
interface Foo {
void bar(Object o);
}
static void doo(Foo f) {
f.bar("baz");
}
public static void main(String[] args) {
doo( x -> {System.out.println(x);});
}
}
答案 0 :(得分:6)
由于界面是standard functional interface
它是一个功能界面,因为它只包含一个抽象方法。此方法接受一个参数并返回[void]值
(为此问题重新编写)
lambda表达式x -> { System.out.println(x); }
可以重写为匿名类。
new Foo() {
@Override
public void bar(Object x) {
System.out.println(x);
}
}
当您致电doo
时,您将此功能界面作为f
传递,然后执行f.bar("baz");
,"baz"
为x
,并打印出来。
所有在一个主要方法中,这看起来像
public static void main(String[] args) {
Foo f = new Foo() {
@Override
public void bar(Object x) {
System.out.println(x);
}
};
f.bar("baz");
}
答案 1 :(得分:3)
参数x
的类型根据specification 推断:
lambda表达式的形式参数可能有声明类型或推断类型。这些样式不能混合:lambda表达式不可能声明其某些参数的类型但是留下其他人推断。只有声明类型的参数才能有修饰符。
在这种情况下,编译器将类型推断为Object
,因为该方法接受具有接受Object
的方法的功能接口。在规范的那一节中也提到了:
如果形式参数具有推断类型,则从lambda表达式所针对的功能接口类型派生这些类型(第15.27.3节)。
答案 2 :(得分:1)
基本上是因为Foo是standard functional interface.
标准功能接口包含一个(且仅一个)抽象函数。 Java 8允许lambdas代替创建接口的实例,以获得更简洁,更清晰的表示法。
答案 3 :(得分:0)
Java Lambda expressions定义了基本规则,