【问题标题】:Type Erasure and the Return type类型擦除和返回类型
【发布时间】:2020-04-17 08:54:23
【问题描述】:
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 类型决定。 另一个问题是 Erasure 将为第 4、5、6 行执行什么类型的操作。 谁能解释一下?

输出:

Employee{name='kamal', add='dcd', doj='45'}
Person{name='Kamal', add='dlf'}

【问题讨论】:

  • 你的术语太离谱了,无法解释这里发生了什么。请简单地谷歌“java类型擦除”并阅读几个小时/天。这段代码没有什么复杂的,它非常基础,完全可以预期这段代码可以编译和工作。

标签: java design-patterns fluent


【解决方案1】:
  • 4、5、6:

    这里没有泛型类型参数,因此编译器将回退到 前泛型行为。没有类型安全。 实际上它在这里显示了一个设计缺陷。

  • 1、2、3:

    类型擦除会导致运行时强制转换为位于 addDoj 的 PersonBuilder 对象的 EmployeeBuilder。

关于模式实现和实际子类的参数化:

可以使用重写方法可以返回超方法的任何子类的语言特性。 这使得通用类型不需要,但不强制返回类型是确切的子类。并且要求覆盖每个子类中的所有方法。

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);
}

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多