繁体   English   中英

类型擦除和返回类型

[英]Type Erasure and the Return type

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'}
  • 4、5、6:

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

  • 1、2、3:

    类型擦除导致在 addDoj 处将运行时强制转换为 PersonBuilder 对象的addDoj

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM