使用Guice通过Types和TypeLiterals在运行时重构泛型类型 [英] Reconstructing generic types at runtime with Guice via Types and 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屋!