Guice泛型 - 我怎样才能让它变得不那么难看?

时间:2010-09-23 10:29:06

标签: java generics coding-style guice

我有一个接口Producer<T>和一个实现FooProducer的具体Producer<Foo>。将它绑在guice中看起来很丑陋:

bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);

我有很多这样的绑定。我尝试过以下方法:

static <T> TypeLiteral<Producer<T>> producer() {
    return new TypeLiteral<Producer<T>>(){};
}

以这种方式拨打电话:

bind(ContainingClass.<Foo>producer()).to(FooProducer.class);

但它在Producer<T> is not specific enough...

的行中给出了错误

我是以错误的方式解决这个问题吗?

3 个答案:

答案 0 :(得分:8)

而不是

bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);

尝试像

这样的便利方法
static <T> Key<Producer<T>> producerOf(Class<T> type) {
  return (Key<Producer<T>>)Key.get(Types.newParameterizedType(Producer.class,type));
}

然后在你的模块中

bind(producerOf(Foo.class)).to(FooProducer.class);

未经检查的演员应该是安全的。密钥是com.google.inject.Key,而类型是com.google.inject.util.Types。

祝你好运

答案 1 :(得分:7)

您可以输入new Key<Producer<Foo>>(){}而不是new TypeLiteral<Producer<Foo>>(){}来保存8个字符。或者使用等效的@Provides方法:

@Provides
public Producer<Foo> provideFooProducer(FooProducer fooProducer) {
  return fooProducer;
}

答案 2 :(得分:3)

我认为由于TypeLiteral的工作方式,您必须实际编写new TypeLiteral<Producer<Foo>>(){},否则将无法获得必要的类型信息。它们利用了这样一个事实,即完全指定其泛型类型的类可以获得有关所检索类型的信息。当您编写new TypeLiteral<Producer<T>>(){}时,您没有指定T是什么,因此该信息不可用。

这是主观的,但我不认为创建类型字面看起来太丑陋,考虑它的作用。

顺便说一句,我不知道你的Producer接口是做什么的,但如果它只是用于生成T的实例(使用的方法没有参数),你可以改用Guice的Provider界面。然后你就必须这样做:

bind(Foo.class).toProvider(FooProvider.class);

您可以在任何地方注入FooProvider<Foo>