Frage

Ich habe ein paar Typen, die wie diese sind

// a value that is aware of its key type (K)
Bar<K>
// something that deals with such values and keys
Foo<V extends Bar<K>, K>

Wie würde man neu Foo, so dass Sie es in Guice verbrauchen könnte? Das Bit ich bin fest ist, wie in die 2. parametrisierte Art von Foo Referenz die K von Bar zu überqueren.

So zum Beispiel,

WildcardType kType = Types.subtypeOf(Object.class);
WildcardType barType = 
   Types.subtypeOf(Types.newParameterizedType(Bar.class, pipeKey));
ParameterizedType fooType = 
   Types.newParameterizedType(Foo.class, pipelineableType, pipeKey);

Wirklich scheint falsch, wie es ist im Grunde:

Foo<V extends Bar<? extends Object>, ? extends Object> 

Was ist nicht das Gleiche wie:

Foo<V extends Bar<K>, K>

Wie im letzteren Fall I weiß , dass K eine konsistente Art ist.

Irgendwelche Ideen?

Prost

Matt

War es hilfreich?

Lösung

Von der JavaDoc für Binder :

  

Guice können derzeit nicht binden oder injizieren   alle ein generischer Typ, wie Set<E>   Typ Parameter müssen vollständig sein   angegeben.

Sie können Bindungen für Foo erstellen, wenn K und V gebunden sind. Wenn Sie Bindungen für Foo für mehr als eine Art von Schlüssel vornehmen müssen, können Sie eine Methode machen, die es einfacher zu machen, diese Bindungen machen. Eine Möglichkeit, das zu tun, ist eine Methode, wie Sie dies in Ihrem Modul zu erstellen:

<K, V extends Bar<K>> AnnotatedBindingBuilder<Foo<V, K>> bind(Class<K> keyType,
    Class<V> barType) {
  ParameterizedType bType = Types.newParameterizedType(Bar.class, keyType);
  ParameterizedType fType = Types.newParameterizedType(Foo.class, barType,
      keyType);

  @SuppressWarnings("unchecked")
  TypeLiteral<Foo<V, K>> typeLiteral =
      (TypeLiteral<Foo<V, K>>) TypeLiteral.get(fType);

  return bind(typeLiteral);
}

Dann, wenn Sie diese Klassen haben:

class StringValue implements Bar<String> {
  ...
}

class StringValueProcessor implements Foo<StringValue, String> {
  ...
}

Sie können eine Bindung wie folgt erstellen:

bind(String.class, StringValue.class).to(StringValueProcessor.class);

... so dass Guice in eine Klasse wie folgt injizieren könnte:

static class Target {
  private final Foo<StringValue, String> foo;

  @Inject
  public Target(Foo<StringValue, String> foo) {
    this.foo = foo;
  }
}

Andere Tipps

Guice Fabrik kann TypeVariable Instanzen nicht bauen. Sie müssen diese Schnittstelle direkt implementieren, wie Sie es brauchen.

Beachten Sie, dass Guice nicht Bindungen für Typen erlauben, die nicht voll qualifiziert sind. Zum Beispiel können Sie ein Map<String, Integer> binden, aber Sie eine Map<K, V> nicht binden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top