【问题标题】:Java8: About Functional InterfaceJava8:关于函数式接口
【发布时间】:2018-10-09 16:37:12
【问题描述】:

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

Rideable rider = Car :: new

它是创建Rideable(接口)还是Car(类)实例? 如果是创建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");
  }
}

【问题讨论】:

    标签: java lambda java-8 method-reference functional-interface


    【解决方案1】:

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

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

    Rideable 功能接口有一个方法 - getCar - 它接受 String 参数并返回 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);
    

    【讨论】:

      【解决方案2】:

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

      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)

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

      如果您正在考虑:

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

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

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

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

      【讨论】:

        【解决方案3】:

        您正在创建“可乘坐”的“汽车”新对象。 所以是的,您正在创建新的“汽车”对象。

        现在 Rideable 被定义为“期待 nameOfTheCar 并通过 getCar() 方法为您提供 Car 实例”,而这正是 "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())。为此,您需要有默认构造函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-28
          • 2018-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-02
          • 1970-01-01
          相关资源
          最近更新 更多