我正在尝试对Builder类进行子类化,如Subclassing a Java Builder class中所述。

那里给出的解决方案非常简单。这是基类:

public class NutritionFacts {

    private final int calories;

    public static class Builder<T extends Builder> {

        private int calories = 0;

        public Builder() {}

        public T calories(int val) {
            calories = val;
            return (T) this;
        }

        public NutritionFacts build() { return new NutritionFacts(this); }
    }

    protected NutritionFacts(Builder builder) {
        calories = builder.calories;
    }
}


和子类:

public class GMOFacts extends NutritionFacts {

    private final boolean hasGMO;

    public static class Builder extends NutritionFacts.Builder<Builder> {

        private boolean hasGMO = false;

        public Builder() {}

        public Builder GMO(boolean val) {
            hasGMO = val;
            return this;
        }

        public GMOFacts build() { return new GMOFacts(this); }
    }

    protected GMOFacts(Builder builder) {
        super(builder);
        hasGMO = builder.hasGMO;
    }
}


但是,return (T) this;中的NutritionFacts.Builder#calories(int)会导致


  NutritionFacts.java使用未经检查或不安全的操作


警告。

给定泛型,为什么这种转换不安全?我知道T extends Builder并且thisBuilder,所以为什么从thisBuilder)到Textends Builder)的转换不安全?演员阵容永不失败,对吧?

最佳答案

它很可能会失败。在

public T calories(int val) {
    calories = val;
    return (T) this;
}


您假设T

public static class Builder<T extends Builder> {


将始终绑定到子类的类型。例如

public static class Real extends Builder<Real>{}


Java中没有办法强制类型参数与声明的类型本身相同。有人很可能有

public static class Fake extends Builder<Real> {}


在这种情况下

Builder<Real> fake = new Fake();
Real real = fake.calories(4);


将失败,并显示ClassCastException

如果您知道这种情况永远不会发生,请忽略警告。强制转换是一个明确的断言,表明您知道自己在做什么。

07-25 21:16
查看更多