簡體   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