Java Builder模式具有通用类型边界
-
27-09-2019 - |
题
我正在尝试使用构建器模式而不是望远镜构造函数创建具有许多参数的类。我正在以约书亚·布洛赫(Joshua Bloch)的有效爪哇的描述,在封闭班上有私人构造师和公共静态建造者类。构建器类确保对象在调用build()之前处于一致的状态,在此时,它将封闭对象的构造委托给私有构造函数。因此
public class Foo {
// Many variables
private Foo(Builder b) {
// Use all of b's variables to initialize self
}
public static final class Builder {
public Builder(/* required variables */) {
}
public Builder var1(Var var) {
// set it
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
然后,我想将类型界限添加到某些变量中,因此需要参数化类定义。我希望Foo类的界限与建造者类别相同。
public class Foo<Q extends Quantity> {
private final Unit<Q> units;
// Many variables
private Foo(Builder<Q> b) {
// Use all of b's variables to initialize self
}
public static final class Builder<Q extends Quantity> {
private Unit<Q> units;
public Builder(/* required variables */) {
}
public Builder units(Unit<Q> units) {
this.units = units;
return this;
}
public Foo build() {
return new Foo<Q>(this);
}
}
}
这可以很好地编译,但是编译器允许我做我认为应该是编译器错误的事情。例如
public static final Foo.Builder<Acceleration> x_Body_AccelField =
new Foo.Builder<Acceleration>()
.units(SI.METER)
.build();
在这里,单位论点不是 Unit<Acceleration>
但 Unit<Length>
, ,但它仍然被编译器接受。
我在这里做错了什么?我想确保在编译时确保单元类型正确匹配。
解决方案
units
应该返回 Builder<Q>
, ,不是一个未生成的 Builder
.
其他提示
尽管 @Daniel的观点是有效的,但至少Eclipse仍然发现了代码中的错误。当然,您对 Quantity
, Unit
和 METER
可能与我组合在一起的简单黑客不同:
interface Quantity {
}
class Acceleration implements Quantity {
}
class Length implements Quantity {
}
public class Unit<Q extends Quantity> {
public static final Unit<Length> METER = new Unit<Length>();
}
public static final Foo.Builder<Acceleration> x_Body_AccelField =
new Foo.Builder<Acceleration>()
.units(Unit.METER) // here the compiler complains
.build();
错误消息是:
The method units(Unit<Acceleration>) in the type Foo.Builder<Acceleration> is
not applicable for the arguments (Unit<Length>)
不隶属于 StackOverflow