Domanda

Sto cercando di creare una classe con molti parametri, utilizzando un Generatore di pattern piuttosto che infilare i costruttori.Io lo sto facendo nel modo descritto da Joshua Bloch Efficace Java, avendo costruttore privato su allegando la classe, e un pubblico statico classe Builder.Il Costruttore della classe garantisce l'oggetto è in uno stato coerente, prima di chiamare il build(), al punto che delega la costruzione della cinta oggetto il costruttore privato.Così

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);
        }

    }

}

Quindi, vorrei aggiungere tipo di limiti per alcune delle variabili, e quindi è necessario parametrizzare la definizione di classe.Voglio i limiti della classe Foo essere la stessa di quella del Generatore di classe.

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);
        }

    }

}

Compila bene, ma il compilatore mi permette di fare cose mi sento dovrebbe essere errori del compilatore.E. g.

public static final Foo.Builder<Acceleration> x_Body_AccelField =
        new Foo.Builder<Acceleration>()
        .units(SI.METER)
        .build();

Qui l'argomento di unità non è Unit<Acceleration> ma Unit<Length>, ma è ancora accettato dal compilatore.

Che cosa sto facendo di sbagliato?Voglio assicurare in fase di compilazione che i tipi di unità di abbinare correttamente.

È stato utile?

Soluzione

units dovrebbe tornare Builder<Q>, non un ungenerified Builder.

Altri suggerimenti

Sebbene @Daniel punto è valido, comunque l'errore nel tuo codice è macchiato da Eclipse almeno.Naturalmente, la tua definizione di Quantity, Unit e METER è probabilmente diverso dal semplicistico hack ho messo insieme:

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();

Il messaggio di errore è:

The method units(Unit<Acceleration>) in the type Foo.Builder<Acceleration> is
not applicable for the arguments (Unit<Length>)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top