Reconstructing generic types at runtime with Guice via Types and TypeLiterals

前端 未结 2 1345
忘掉有多难
忘掉有多难 2021-01-06 19:52

I have a few types that are like this

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

        
相关标签:
2条回答
  • 2021-01-06 20:37

    From the JavaDoc for Binder:

    Guice cannot currently bind or inject a generic type, such as Set<E> all type parameters must be fully specified.

    You can create bindings for Foo when K and V are bound. If you need to make bindings for Foo for more than one type of key, you can make a method that makes it easier to do these bindings. One way to do that is to create a method like this in your module:

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

    Then if you have these classes:

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

    You can create a binding like this:

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

    ...so that Guice could inject into a class like this:

    static class Target {
      private final Foo<StringValue, String> foo;
    
      @Inject
      public Target(Foo<StringValue, String> foo) {
        this.foo = foo;
      }
    }
    
    0 讨论(0)
  • 2021-01-06 20:55

    Guice's factory cannot build TypeVariable instances. You'll need to implement this interface directly as you need it.

    Note that Guice doesn't allow bindings for types that aren't fully-qualified. For example, you can bind a Map<String, Integer> but you can't bind a Map<K, V>.

    0 讨论(0)
提交回复
热议问题