e really don't gain much from this example
//Example #1
Automobile honda = auto.auto("honda", "Accord", (short) 2006);
honda.what();
//Example #1
Automobile bmw = auto.auto("BMW", "530i", (short) 2006);
bmw.what();
System.out.println();
}
}
输出结果
This Automobile is a2006 honda Accord.
This Automobile is a2006 BMW 530i.
说明
用户应该清楚的第一件事是这个基本示例没有那么实用。这是一种相当迂回的创建对象实例的方式。实际上,几乎可以肯定,你不会经历所有这些麻烦来创建一个 Automobile 实例,但是为了概念的完整性,还是要提及。
使用构造函数的方法引用的主要步骤有:
- 定义一个只有抽象方法的函数式接口,该方法的返回类型与你打算使用该对象进行构造函数引用的对象相同。
- 创建一个类,该类的构造函数与函数式接口的抽象方法匹配。
- 使用对步骤 #2 中定义的构造函数的方法引用,实例化函数式接口的实例。
译注:构造函数的方法引用格式为 类名 :: new
- 在步骤 #2 中使用构造函数引用实例化类的实例,例如
MyClass x = ConstructorReference.AbstractMethod (x, y, z…)
构造函数引用与泛型一起使用的时候变得更有用。通过使用泛型工厂方法,可以创建各种类型的对象。
让我们看一看。
//step #1 - Create a funnctional interface.
interface FuncInt<Ob, X, Y, Z> {
//contains one and only abstract method
Ob func(X make, Y model, Z year);
}
//step #2 - Create a Generic class providing a constructor compatible with FunInt.func()'s definition
class Automobile<X, Y, Z> {
//Automobile Member Variables
private X make;
private Y model;
private Z year;
//Automobile Constructor
public Automobile(X make, Y model, Z year) {
this.make = make;
this.model = model;
this.year = year;
}
protected void what() {
System.out.println("This Automobile is a " + year + " " + make + " " + model + ".");
}
}
//step #3 - Create a Non-Generic class providing a constructor compatible with FunInt.func()'s definition
class Plane {
//Automobile Member Variables
private String make;
private String model;
private int year;
//Plane Constructor
public Plane(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;//Automatic unboxing
}
protected void what() {
System.out.println("This Plane is a " + year + " " + make + " " + model + ".");
}
}
//Step #3 - Class making use of method reference with generics
public class ConstrRefGen {
//Here is where the magic happens
static <Ob, X, Y, Z> Ob factory(FuncInt<Ob, X, Y, Z> obj, X p1, Y p2, Z p3) {
return obj.func(p1, p2, p3);
}
public static void main(String[] args) {
System.out.println();
//Example #1
FuncInt<Automobile<String, String, Integer>, String, String, Integer> auto_cons = Automobile<String, String, Integer>::new;
Automobile<String, String, Integer> honda = factory(auto_cons, "Honda", "Accord", 2006);
honda.what();
//Example #2
FuncInt<Plane, String, String, Integer> plane_cons = Plane::new;
Plane cessna = factory(plane_cons, "Cessna", "Skyhawk", 172);
cessna.what();
System.out.println();
}
}
输出结果
This Automobile is a 2006 Honda Accord.
This Plane is a 172 Cessna Skyhawk.
另请参阅:Java 中的 struct :如何像专业人士一样处理它们
说明
这里有很多东西需要消化。事实上,如果你以前从未深入研究过泛型,那么这些代码看上去可能相当晦涩。让我们分解一下。
我们做的第一件事是创建一个通用的函数式接口。注意细节。我们有四个泛型类型参数:Ob、X、Y、Z。
- Ob 代表要引用其构造函数的类。
- X,Y,Z 代表该类的构造函数的参数。
如果我们替换泛型方法占位符,抽象方法可能是这样的: SomeClass func (String make, String model, int year)
。注意,由于我们使接口具有了泛型,所以可以指定任何返回类型或我们希望返回的类实例。这释放了构造函数引用的真正潜力。
接下来的两个部分相对简单,我们创建了相同的类,一个泛型类和一个非泛型类,以演示