【问题标题】:Reconstructing generic types at runtime with Guice via Types and TypeLiterals在运行时使用 Guice 通过 Types 和 TypeLiterals 重构泛型类型
【发布时间】:2009-07-11 18:44:09
【问题描述】:

我有几种是这样的

// 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>

如何重新创建 Foo 以便您可以在 Guice 中使用它?我坚持的一点是如何将 K 从 Bar 交叉引用到 Foo 的第二个参数化类型。

例如,

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

这似乎是错误的,因为它基本上是:

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

这与以下内容不同:

Foo<V extends Bar<K>, K>

在后一种情况下,我知道 K 是一致类型。

有什么想法吗?

干杯

马特

【问题讨论】:

    标签: generics reflection runtime guice


    【解决方案1】:

    来自Binder 的 JavaDoc:

    Guice 当前无法绑定或注入 泛型类型,例如Set&lt;E&gt; all 类型参数必须完全 指定。

    KV 绑定时,您可以为Foo 创建绑定。 如果您需要为不止一种类型的密钥为Foo 进行绑定,您可以创建一种更容易进行这些绑定的方法。一种方法是在您的模块中创建这样的方法:

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

    如果你有这些类:

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

    您可以像这样创建绑定:

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

    ...这样 Guice 就可以像这样注入到一个类中:

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

    【讨论】:

    • 有趣,我没想过以这种方式绑定。我真正在寻找能够搜索一组与可能包含某些类型参数的规范匹配的绑定的能力,例如所有绑定都是 Foo,String> 虽然我想在这种情况下只需查找 Foo,String>... hmmm
    • 是的,这也是我的 Q,我已经以一种迄今为止有效的方式实现了它......但一直想知道如何将它扩展到更一般的情况。经过反思,我不确定它是否需要,因为它实际上只是一个通配符。我需要再考虑一下...
    【解决方案2】:

    Guice 的工厂无法构建 TypeVariable 实例。您需要根据需要直接实现此接口。

    请注意,Guice 不允许对不完全限定的类型进行绑定。例如,您可以绑定Map&lt;String, Integer&gt;,但不能绑定Map&lt;K, V&gt;

    【讨论】:

      猜你喜欢
      • 2014-08-22
      • 2020-08-19
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多