使用Guice通过Types和TypeLiterals在运行时重构泛型类型 [英] Reconstructing generic types at runtime with Guice via Types and TypeLiterals

查看:156
本文介绍了使用Guice通过Types和TypeLiterals在运行时重构泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  //一个知道其键类型(K)的值, 
Bar< K>
//处理这些值和键的东西
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   

这不同于:

  Foo< V extends Bar< K>,K> 

正如后一种情况,我知道 K是一个一致的类型。



任何想法?



干杯

马特

解决方案

从JavaDoc for 活页夹


Guice目前无法绑定或注入
a泛型类型,例如 Set 所有
类型参数必须完全指定为


K Foo 创建绑定c $ c>和 V 被绑定。
如果您需要针对多种类型的键为 Foo 进行绑定,您可以创建一个方法来更轻松地完成这些绑定。一种方法是在你的模块中创建一个像这样的方法:

 < K,V extends Bar< K> > AnnotatedBindingBuilder< Foo< V,K>> (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实现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;
}
}


I have a few types that are like this

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

How would one recreate Foo such that you could consume it in Guice? The bit I'm stuck on is how to cross reference the K from Bar to the 2nd parameterized type of Foo.

So for example,

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

Really this seems wrong as it's basically:

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

Which is not the same thing as:

Foo<V extends Bar<K>, K>

As in the latter case I know that K is a consistent type.

Any ideas?

Cheers

Matt

解决方案

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

这篇关于使用Guice通过Types和TypeLiterals在运行时重构泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆