我有一些像这样的类型
// 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 是一致的类型。
有任何想法吗?
干杯
马特
最佳答案
来自 Binder 的 JavaDoc :
Guice cannot currently bind or inject a generic type, such as
Set<E>
all type parameters must be fully specified.
您可以为
Foo
创建绑定(bind)当K
和 V
绑定(bind)。如果您需要绑定(bind)
Foo
对于不止一种类型的键,您可以创建一种方法来更轻松地进行这些绑定(bind)。一种方法是在你的模块中创建一个这样的方法:<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):
class StringValue implements Bar<String> {
...
}
class StringValueProcessor implements Foo<StringValue, String> {
...
}
您可以像这样创建绑定(bind):
bind(String.class, StringValue.class).to(StringValueProcessor.class);
...这样 Guice 就可以注入(inject)这样的类:
static class Target {
private final Foo<StringValue, String> foo;
@Inject
public Target(Foo<StringValue, String> foo) {
this.foo = foo;
}
}
关于generics - 在运行时使用 Guice 通过 Types 和 TypeLiterals 重构泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1114384/