简体   繁体   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);
    }
}

I have two questions to ask in these lines of code.在这些代码行中,我有两个问题要问。 The lines of code are related to the Fluent(design pattern) Recursive Generics.代码行与 Fluent(设计模式)递归泛型相关。 First is as Line 1, 2, 3 are running that means the Return type of PersonBuilder method is EmployeeBuilder, but I have also studied that the type erasure replaces the type with the bounds, So it should be replacing with PersonBuilder(EmployeeBuilder) and the program should not be running.首先是第 1、2、3 行正在运行,这意味着 PersonBuilder 方法的返回类型是 EmployeeBuilder,但我也研究过类型擦除将类型替换为边界,所以它应该替换为 PersonBuilder(EmployeeBuilder) 和程序不应运行。 Because when in case of generics the input parameters of a function will be decided by the type Erasure.因为在泛型的情况下,函数的输入参数将由 Erasure 类型决定。 The other question is what type Erasure is going to do for the line Number 4,5,6.另一个问题是 Erasure 将为第 4、5、6 行执行什么类型的操作。 Can anyone explain?谁能解释一下?

Output:输出:

Employee{name='kamal', add='dcd', doj='45'}
Person{name='Kamal', add='dlf'}
  • 4, 5, 6: 4、5、6:

    Here there is no generic type parameter, hence the compiler will fallback on the pre-generics behavior.这里没有泛型类型参数,因此编译器将回退到泛型之前的行为。 No type-safeness.没有类型安全性。 In effect it shows a design flaw here.实际上,它在这里显示了设计缺陷。

  • 1, 2, 3: 1、2、3:

    Type erasure results in a runtime cast to EmployeeBuilder of the PersonBuilder object at addDoj .类型擦除导致在 addDoj 处将运行时强制转换为 PersonBuilder 对象的addDoj

About the pattern implementation and the parametrisation with the actual child class:关于模式实现和实际子类的参数化:

One can use the language feature that an overriden method may return any child class of the super method.可以使用重写方法可以返回超级方法的任何子类的语言特性。 This makes generic typing unneeded, but does not enforce the return type being the exact child class.这使得不需要泛型类型,但不会强制返回类型是确切的子类。 And requires all methods in every child class to be overriden.并要求覆盖每个子类中的所有方法。

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