Guice:如何为所有类型绑定泛型?
Guice: how do I bind generics for ALL types?
假设我的代码中经常重复以下模式:
class A<T> {
@Inject
public A(List<T> list) {
// code
}
}
我想将全部List<T>
绑定到ArrayList<T>
。
我知道我可以使用 TypeLiteral
s 来绑定一个显式的原始类型,例如 List<String>
,但是是否可以对所有类型执行此操作?
基本上,这段代码应该不会失败,因为我没有明确绑定列表:
injector.getInstance(new Key<A<Integer>>(){});
这在 Guice 中是不可能的。在内部 Guice 只不过是一个 HashMap<Key, Provider<?>>
,其中 Key
表示一个可选的绑定注释和一个单一的完全限定类型。要匹配 "pattern" 类型,需要 Key 的行为更像谓词,这需要非常不同的体系结构,这会使绑定查找速度变慢。
此外,尽管您可能将 List 用作简单示例,但请记住,Guice 绑定最好保留给可能在生产或测试中发生变化的等效实现。除了具有非常不同的特定于算法的性能特征外,列表实现在处理 null
项的能力上也各不相同,一旦您为给定算法选择了理想的列表实现,您就不太可能需要更改它—尤其是在应用程序范围的配置中。
如果您确实希望能够使用 Guice 样式的配置来改变您的通用实现,请创建一个非常小的工厂,例如 ListFactory
:
public class ListFactory {
public <T> List<T> createFooBarList() { return new ArrayList<T>(); }
public <T> List<T> createSomeOtherList() { return new LinkedList<T>(); }
}
假设我的代码中经常重复以下模式:
class A<T> {
@Inject
public A(List<T> list) {
// code
}
}
我想将全部List<T>
绑定到ArrayList<T>
。
我知道我可以使用 TypeLiteral
s 来绑定一个显式的原始类型,例如 List<String>
,但是是否可以对所有类型执行此操作?
基本上,这段代码应该不会失败,因为我没有明确绑定列表:
injector.getInstance(new Key<A<Integer>>(){});
这在 Guice 中是不可能的。在内部 Guice 只不过是一个 HashMap<Key, Provider<?>>
,其中 Key
表示一个可选的绑定注释和一个单一的完全限定类型。要匹配 "pattern" 类型,需要 Key 的行为更像谓词,这需要非常不同的体系结构,这会使绑定查找速度变慢。
此外,尽管您可能将 List 用作简单示例,但请记住,Guice 绑定最好保留给可能在生产或测试中发生变化的等效实现。除了具有非常不同的特定于算法的性能特征外,列表实现在处理 null
项的能力上也各不相同,一旦您为给定算法选择了理想的列表实现,您就不太可能需要更改它—尤其是在应用程序范围的配置中。
如果您确实希望能够使用 Guice 样式的配置来改变您的通用实现,请创建一个非常小的工厂,例如 ListFactory
:
public class ListFactory {
public <T> List<T> createFooBarList() { return new ArrayList<T>(); }
public <T> List<T> createSomeOtherList() { return new LinkedList<T>(); }
}