Java8:关于功能接口

Pat*_* C. 6 java lambda java-8 functional-interface method-reference

我想问一下与功能接口相关的以下代码.我很困惑:

Rideable rider = Car :: new
Run Code Online (Sandbox Code Playgroud)

它是创建Rideable(接口)还是Car(类)实例?如果它正在创建一个Car对象,那么构造函数new Car()(即没有参数)应该不存在,那么为什么它可以有效呢?

我一直在阅读本教程,但仍然无法弄明白.

@FunctionalInterface 
interface Rideable {
  Car getCar (String name);
}

class Car {
  private String name;

  public Car (String name) {
    this.name = name;
  }
}

public class Test {
  public static void main(String[] args) {
    Rideable rider = Car :: new; 
    Car vehicle = rider.getCar("MyCar");
  }
}
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 5

它是创建Rideable(接口)还是Car(类)实例?

它正在创建一个(实现)Rideable接口的实例.

所述Rideable功能接口有一个单一的方法- getCar-接受一个String参数,并返回Car实例.

public Car (String name)构造函数接受一个String参数,并产生一个Car实例.

因此,方法引用Car::new(在这种情况下不引用无参数构造函数)可以用作Rideable接口的实现.

如果它有助于澄清混淆,这里是一个lambda表达式,等同于Car::new方法引用:

Rideable rider = (String s) -> new Car(s);
Run Code Online (Sandbox Code Playgroud)

要么

Rideable rider = s -> new Car(s);
Run Code Online (Sandbox Code Playgroud)


Ale*_*amo 1

您正在使用 Lambda 语法来实现getCar()Rideable 接口的方法,其中使用 Lambda 的简洁语法省略了以下匿名类程序:

Rideable rideable = new Rideable() {
    @Override
    public Car getCar(String name) {
        return new Car(name);
    }
};
Run Code Online (Sandbox Code Playgroud)

这是 Java 7 代码。您可以使用 Lambda 表达式实现相同的效果:

Rideable rider = name -> new Car(name);
Run Code Online (Sandbox Code Playgroud)

或者如您的示例所示,使用方法参考:

Rideable rider = Car::new;
Run Code Online (Sandbox Code Playgroud)

因此,getCar(String)Rideable 对象的方法可以用作new Car(String).

作为问题的答案,您正在创建一个Car实现 Rideable 接口的类实例。这是无需使用关键字即可实现接口的另一种方法implement

如果您正在考虑:

Car auto = Car("MyCar")::new;
Run Code Online (Sandbox Code Playgroud)

或者

Car auto = Car::new;
Car vehicle = auto::getCar("MyCar");
Run Code Online (Sandbox Code Playgroud)

或者

Car vehicle = Rideable::new::getCar("MyCar");
Run Code Online (Sandbox Code Playgroud)

所有这些例子都是wrong方法。我给您提供这个示例是因为这些是我们在谈论 Lambda 表达式或方法引用时可能犯的常见错误。