我有几种类似
的类型// 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是一致的类型。
有什么想法吗?
干杯
马特
答案 0 :(得分:4)
来自Binder的JavaDoc:
Guice目前无法绑定或注入 通用类型,例如
Set<E>
全部 类型参数必须完整 指定。
绑定Foo
和K
时,您可以为V
创建绑定。
如果需要为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;
}
}
答案 1 :(得分:0)
Guice的工厂无法构建TypeVariable
个实例。您需要根据需要直接实现此接口。
请注意,Guice不允许对不完全限定的类型进行绑定。例如,您可以绑定Map<String, Integer>
,但无法绑定Map<K, V>
。