我正在尝试对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
并且this
是Builder
,所以为什么从this
(Builder
)到T
(extends 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
。如果您知道这种情况永远不会发生,请忽略警告。强制转换是一个明确的断言,表明您知道自己在做什么。