汎用型の境界を持つJavaビルダーパターン
-
27-09-2019 - |
質問
私は、望遠鏡コンストラクターではなくビルダーパターンを使用して、多くのパラメーターを備えたクラスを作成しようとしています。私はこれを、ジョシュア・ブロッホの効果的なJavaによって説明されており、囲いのクラスにプライベートコンストラクターとパブリックスタティックビルダークラスを持っています。ビルダークラスは、オブジェクトが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