Я пытаюсь создать класс с множеством параметров, используя шаблон Builder, а не телескопические конструкторы. Я делаю это способом, описанным в «Эффективной Java» Джошуа Блоха, имеющим закрытый конструктор для включающего класса и открытый статический класс Builder. Класс Builder гарантирует, что объект находится в непротиворечивом состоянии перед вызовом 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 были такими же, как и у класса Builder.
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>
, но он все еще принимается компилятором.
Что я здесь не так делаю? Я хочу убедиться, что во время компиляции типы юнитов совпадают правильно.