Java Guice无界泛型绑定

Java Guice无界泛型绑定,java,generics,guice,Java,Generics,Guice,我希望提供泛型实例,而不在模块实现中显式说明泛型参数 假设我有一个非常优化的Map实现,希望每个人都能使用它 class MyVeryOptimizedHashMap<K, V> implements Map<K, V> {} 类MyVeryOptimizedHashMap实现映射{} 我知道,以下用法不是最好的设计模式,但就本例而言,这是一个有效的要求: class SomeInjectee { @Inject private Map<String,

我希望提供泛型实例,而不在模块实现中显式说明泛型参数

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

class MyVeryOptimizedHashMap<K, V> implements Map<K, V> {}
类MyVeryOptimizedHashMap实现映射{} 我知道,以下用法不是最好的设计模式,但就本例而言,这是一个有效的要求:

class SomeInjectee {
  @Inject
  private Map<String, Integer> myMap;
}
class-SomeInjectee{
@注入
私人地图myMap;
}
要将此实例绑定到我选择的提供程序,请执行以下模块声明:

class GenericMapModule extends AbstractModule {
  protected void configure() {
    bind(new TypeLiteral<Map<String, Integer>>() {}).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap<String, Integer>>>() {});
  }
}
类GenericMapModule扩展了AbstractModule{
受保护的void configure(){
bind(new-TypeLiteral(){}).toProvider(new-TypeLiteral(){});
}
}
问题是我必须显式地声明泛型类型参数,但我不可能对所有可能的类型都这样做:

class SomeOtherInjectee{
  @Inject
  private Map<SomeUnknownKey, Long> myMap;
}
class SomeOtherInjectee{
@注入
私人地图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扩展了AbstractModule{
受保护的void configure(){
绑定(新的TypeLiteral>(){
公共地图获取(){
返回新的MyVeryOptimizedHashMap();
}
});
}
}
类其他被注射者{
私人地图myMap;
@注入
void setMap(Map mapInstance){
myMap=(Map)mapInstance;
}
}
我要找的是这样的东西:

class GenericModule extends AbstractModule {
  protected void configure() {
    bind(TypeLiteral.anyGenericVariant(Map.class)).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap>>(){});        
  }
}
class GenericModule扩展了AbstractModule{
受保护的void configure(){
bind(TypeLiteral.anyGenericVariant(Map.class)).toProvider(newtypeliteral(){});
}
}

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

class SomeOtherInjectee {
    private Map<SomeUnknownKey, Long> myMap = newOptimizedMap();
class SomeOtherInjectee{
私有映射myMap=newOptimizedMap();
如果这不适用,那么正如您所见,Guice在泛型方面非常精确,即每个泛型变体代表一个唯一的绑定。因此anyGenericVariant实际上必须列出所有可能的变体并提前进行绑定。疯狂

在这种情况下,您可以使用TypeListener注册自定义注入

class SomeOtherInjectee {
    @InjectOptimizedMap private Map<SomeUnknownKey, Long> myMap;
class SomeOtherInjectee{
@InjectOptimizedMap私有映射myMap;
或者您所做的任何自定义注入注释


请参阅如何进行自定义注入。

正如我所提到的,这是一个示例,我的实际用例与此不同。因此,我需要在模块定义中解决这个问题(可能使用一些Key或TypeLiteral类的私有构造函数)让注入者保持原样。如果只有KeyTypeLiteral匹配可以被破解的话,Guice实际上是相当懒惰的。用TypeListener的方式有什么不对?你需要c'tor注入吗?