6

コンストラクターを伸縮させるのではなく、Builderパターンを使用して、多くのパラメーターを持つクラスを作成しようとしています。JoshuaBlochのEffectiveJavaで説明されている方法でこれを行っており、囲んでいるクラスにプライベートコンストラクターがあり、パブリック静的ビルダークラスがあります。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();

ここで、units引数はではありませんUnit<Acceleration>Unit<Length>、コンパイラーによって受け入れられます。

私はここで何が間違っているのですか?コンパイル時に、ユニットタイプが正しく一致することを確認したいと思います。

4

2 に答える 2

7

unitsBuilder<Q>生成されていないものではなく、を返す必要がありますBuilder

于 2010-05-17T22:27:53.127 に答える
0

@Danielのポイントは有効ですが、それでもコード内のエラーは少なくともEclipseによって検出されます。もちろん、あなたの定義はQuantity、おそらく私がまとめた単純なハックとは異なりますUnitMETER

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>)
于 2010-05-17T22:47:23.097 に答える