Java8: 关于功能接口

Java8: About Functional Interface

我想问一下下面这段函数式接口相关的代码。 我很困惑:

Rideable rider = Car :: new

它是在创建一个Rideable(接口)还是Car(class)实例? 如果它正在创建一个 Car 对象,构造函数 new Car() (即没有参数)应该不存在,那么这怎么会有效?

我一直在阅读 this tutorial ,但仍然无法理解。

@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");
  }
}

Is it creating a Rideable (interface) or Car (class) instance?

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

Rideable 功能接口只有一个方法 - getCar - 接受一个 String 参数和 returns 一个 Car 实例。

public Car (String name) 构造函数接受一个 String 参数并生成一个 Car 实例。

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

如果有助于澄清混淆,这里有一个等同于 Car::new 方法参考的 lambda 表达式:

Rideable rider = (String s) -> new Car(s);

Rideable rider = s -> new Car(s);

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

Rideable rideable = new Rideable() {
    @Override
    public Car getCar(String name) {
        return new Car(name);
    }
};

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

Rideable rider = name -> new Car(name);

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

Rideable rider = Car::new;

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

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

如果您正在考虑:

Car auto = Car("MyCar")::new;

Car auto = Car::new;
Car vehicle = auto::getCar("MyCar");

Car vehicle = Rideable::new::getCar("MyCar");

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

您正在创建 "Car" 的新对象,即 "Rideable"。 所以是的,您正在创建新的 "Car" 对象。

现在 Rideable 被定义为 "expecting nameOfTheCar and gives you Car instance via getCar() method" 而这正是 "Car::new" 正在做的事情。

Car::new 

在此示例中与(分配给 Rideable 的)相同

carName -> new Car(carName)

现在上面的行为是使用 lambda 包装的,Java7 看起来像下面这样:

Rideable rideable = new Rideable() {
    @Override
    public Car getCar(String carName ) {
        return new Car(carName);
    }
};

现在假设您有另一个界面

@FunctionalInterface
interface SelfRideable {
    Car getSelfDriven();
}

现在如果你这样做

SelfRideable selfDriven = Car::new;

然后它不会编译,因为现在它的方法没有任何参数(getSelfDriven())。为此,您需要具有默认构造函数。