class Person
{
String name;
String add;
Person(){}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", add='" + add + '\'' +
'}';
}
public Person(String name, String add)
{
this.name=name;
this.add=add;
}
}
class PersonBuilder<E extends PersonBuilder<E>>{
String name;
String add;
E addName(String name)
{
this.name=name;
return (E)this;
}
E addAdd(String add)
{
this.add=add;
return (E)this;
}
Person build()
{
return new Person(name,add) ;
}
}
class Employee extends Person{
String doj;
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", add='" + add + '\'' +
", doj='" + doj + '\'' +
'}';
}
Employee(String name, String add, String doj)
{
super(name,add);
this.doj=doj;
}
}
class EmployeeBuilder extends PersonBuilder<EmployeeBuilder>{
String doj;
EmployeeBuilder addDoj(String doj)
{
this.doj=doj;
return this;
}
Employee build()
{
return new Employee(name,add,doj);
}
}
public class FluentBuilderRecursiveGenerics{
public static void main(String[] args) {
1. EmployeeBuilder eb=new EmployeeBuilder();
2. Employee e=eb.addName("kamal").addAdd("dcd").addDoj("45").build();
3. System.out.println(e);
4. PersonBuilder pb=new PersonBuilder();
5. Person p=pb.addName("Kamal").addAdd("dlf").build();
6. System.out.println(p);
}
}
我在这些代码行中有两个问题要问。代码行与Fluent(设计模式)递归泛型相关。首先是因为第1、2、3行正在运行,这意味着PersonBuilder方法的返回类型为EmployeeBuilder,但我还研究了类型擦除将类型替换为边界,因此应将其替换为PersonBuilder(EmployeeBuilder),然后程序不应运行。因为在泛型的情况下,函数的输入参数将由Erasure类型决定。另一个问题是数字4,5,6行的擦除类型是什么。谁能解释?
输出:
Employee{name='kamal', add='dcd', doj='45'}
Person{name='Kamal', add='dlf'}
4,5,6:
这里没有通用类型参数,因此编译器将在泛型行为。没有类型安全性。 实际上,它在这里显示出设计缺陷。
1、2、3:
类型擦除导致运行时强制转换为PersonBuilder对象的EmployeeBuilder,位于addDoj
。
关于模式实现和实际子类的参数设置:
可以使用一种语言功能,即重写方法可以返回super方法的任何子类。 这使得不需要通用类型输入,但不会强制返回类型是确切的子类。并要求覆盖每个子类中的所有方法。
public class A {
String name;
A addName(String name) {
this.name = name;
return this;
}
}
class B extends A {
@Override
B addName(String name) {
return (B) super.addName(name);
}
}
public static void main(String args[]) {
B b = new B().addName("xxx");
System.out.println("name = " + b.name);
}