类型擦除和返回类型

问题描述 投票:-1回答:1
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'}
java design-patterns fluent
1个回答
0
投票
  • 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.