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()
)。为此,您需要具有默认构造函数。
我想问一下下面这段函数式接口相关的代码。 我很困惑:
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()
)。为此,您需要具有默认构造函数。