質問

私は、望遠鏡コンストラクターではなくビルダーパターンを使用して、多くのパラメーターを備えたクラスを作成しようとしています。私はこれを、ジョシュア・ブロッホの効果的な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, 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>)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top