java - Guice 无限泛型绑定(bind)

标签 java generics guice

我想提供通用实例而不在模块实现中明确声明通用参数。

假设我有一个非常优化的 Map 实现并希望每个人都使用它。

class MyVeryOptimizedHashMap<K, V> implements Map<K, V> {}

我知道,下面的用法不是最好的设计模式,但为了这个例子,这是一个有效的要求:

class SomeInjectee {
  @Inject
  private Map<String, Integer> myMap;
}

在模块声明之后将此实例绑定(bind)到我选择的提供者:

class GenericMapModule extends AbstractModule {
  protected void configure() {
    bind(new TypeLiteral<Map<String, Integer>>() {}).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap<String, Integer>>>() {});
  }
}

问题是我必须显式声明泛型类型参数,我不可能对所有可能的类型都这样做:

class SomeOtherInjectee{
  @Inject
  private Map<SomeUnknownKey, Long> myMap;
}

这解决了我的问题,但不是很优雅:

class GenericModule extends AbstractModule {
  protected void configure() {
    bind(new TypeLiteral<Map<?, ?>>() {}).toProvider(new Provider<Map<?,?>>() {
      public Map<?, ?> get() {
        return new MyVeryOptimizedHashMap();
      }
    });
  }
}

class SomeOtherInjectee {
  private Map<SomeUnknownKey, Long> myMap;

  @Inject
  void setMap(Map<?, ?> mapInstance) {
    myMap = (Map<SomeUnknownKey, Long>) mapInstance;
  }
}

我正在寻找的是这样的东西:

class GenericModule extends AbstractModule {
  protected void configure() {
    bind(TypeLiteral.anyGenericVariant(Map.class)).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap>>(){});        
  }
}

最佳答案

如果适用于您的情况,我会尝试静态实用方法。

class SomeOtherInjectee {
    private Map<SomeUnknownKey, Long> myMap = newOptimizedMap();

如果这不适用,那么正如您所见,Guice 在泛型方面非常精确,即每个泛型变体代表一个唯一的绑定(bind)。所以 anyGenericVariant 实际上必须列出所有可能的变体并提前进行绑定(bind)。疯了。

在这种情况下,您可以做的是使用 TypeListener 注册自定义注入(inject)。看起来像

class SomeOtherInjectee {
    @InjectOptimizedMap private Map<SomeUnknownKey, Long> myMap;

或您所做的任何自定义注入(inject)注释。

参见 here for the full example and explanation关于如何进行自定义注入(inject)。

关于java - Guice 无限泛型绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16065239/

相关文章:

java - 在 Kotlin 中使用 Room 的 @ForeignKey 作为 @Entity 参数

java - 如何访问此层次结构中的文件?

java - 尝试从文本文件中读取

java - 使用带有 AbstractThreadedSyncAdapter 的 RoboGuice 上下文注入(inject)

java - Guice 的 Names.bindProperties(Binder, Properties) 的 CDI (Weld) 等价物是什么?

java - Guice:通过方法创建对象

java - += 运算符不适用于字符串

java - 继承层次结构对泛型的限制是什么?

scala - 添加和扩展通用编写器特征以进行逐步数据存储的最佳方法

java - 为什么我不能创建字符串和通用对象的映射