【问题标题】:Guice, Generics, and TypeLiteralsGuice、泛型和 TypeLiterals
【发布时间】:2014-08-22 11:16:58
【问题描述】:

假设我有这个:

public class Foo<T> {
    @Inject public Foo(Class<T> tClass);
}

public class FooProvider<T> implements Provider<Foo<T>> {
    @Inject private TypeLiteral<T> type;
    @Override
    public Foo<T> get() {
        Class<T> rawType = (Class<T>) type.getRawType();
        return new Foo<>(rawType);
    }
}

如果我有,在一个模块中,

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

会自动绑定Foo&lt;Integer&gt;Foo&lt;String&gt;等,还是必须单独提供?还假设我无法修改Foo,以便它使用TypeLiteral&lt;T&gt; 而不是Class&lt;T&gt;

相关问题:假设我有 Guava 的 TypeToken&lt;T&gt;(或其他类似的“类型令牌”类),并且我有一个将 TypeLiteral&lt;T&gt; 转换为 TypeToken&lt;T&gt; 的提供程序。类似的原理会起作用吗?

【问题讨论】:

  • 为什么不自己试试呢?
  • IMO guice 在处理泛型方面做得很差。有时,正确绑定泛型似乎是一个非常有趣的过程。

标签: generics guava guice typeliteral


【解决方案1】:

给定的绑定

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

将只绑定只绑定类“Foo”(不指定泛型类型)到提供者。您需要使用 TypeLiteral 来指定泛型。您可以使用以下语句获得所需的行为:

bind(new TypeLiteral<Foo>(){}).toProvider(FooProvider.class);

【讨论】:

  • 仍然固执地拒绝为我编译。表示 FooProvider.class 不能转换为 Class&lt;? extends Provider&lt;? extends Foo&gt;&gt;。任何调整,使其可以工作...?
  • 我认为这个答案解决了问题的精神,但不能解决您的问题。请参阅我的其他答案以解决您的问题。
【解决方案2】:

试试这个:

类:

public class Foo<T> {
    @Inject public Foo(Class<T> tClass);
}

我猜你希望 JIT 在注入类时自动提供泛型类型,但这不会发生。这不是 Guice 的 JIT 的工作方式。您需要绑定您计划使用的每个泛型类型。看下面的代码sn-p(注意我们不是绑定Foo,我们是绑定将要注入Foo的类):

bind(new TypeLiteral<Class<MyType>>(){}).toInstance(MyType.class);

要获取实例,需要将类型定义为泛型。

@Inject Foo<MyType> foo

要直接从注入器轮询它,您需要具体说明泛型类型

injector.getInstance(Key.get((new TypeLiteral<Foo<MyType>>(){})));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    相关资源
    最近更新 更多