没有类型的Lambda表达式

时间:2016-10-18 20:09:59

标签: java lambda java-8

我理解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);});
    }

}

4 个答案:

答案 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定义了基本规则,

  • 对于一个参数,括号是可选的[例如:a-> a a; (a)-> a b; ]
  • 可以声明或自动检测参数类型 [例如:(int a,int b)-> a + b; (a,b)-> a + b; ]
  • 如果我们要声明参数类型,则必须加括号 [例如:a-> a * a; (int a)-> a * a; ]
  • 对于单行表达式,花括号是可选的[例如:a-> a a; a-> {return a a}; ]
  • 或单行表达式return关键字是可选的[例如:a-> a a; a-> {return a a}; ]

您可以在Basics Lambda expression in java 8

制定更多规则