我已经开始学习guice并偶然发现使用guice注入泛型类型。网中的所有解决方案似乎都使用new TypeLiteral<Generic<Type>>(){}
之类的东西。但是,当我尝试这样做时,它表明TypeLiteral
的构造函数受到保护。如何使用TypeLiteral.get()
执行通用注入?示例代码:
public interface Repository<T> {
void save(T item);
T get(int id);
}
public StringRepository implements Repository<String> {
@Override
public void save(String item) {
// do saving
}
@Override
public String get(int id) {
// get item and return
return item;
}
}
public MyModule extends AbstractModule{
@Override
public void configure() {
....
TypeLiteral<Repository<String>> typeLiteral =
TypeLiteral.get((Repository<String>.class));//does not work
//does not work either because constructor is protected
bind(new TypeLiteral<Repository<String>>(){}).to(StringRepository.class);
}
}
答案 0 :(得分:3)
您的文字说new TypeLiteral<Generic<Type>>(){}
。您的屏幕截图显示new TypeLiteral<Generic<Type>>()
。第一个是{}
,第二个没有。这些花括号是关键的 - 它们将表达式从创建TypeLiteral
的新实例改为创建 TypeLiteral
的匿名子类并创建该子类的实例。
这是解决泛型类型擦除的必要条件。为了使TypeLiteral
能够实现其目的,它必须在运行时知道泛型类型参数是什么。类型擦除意味着泛型类的简单实例在运行时不知道它的类型参数是什么。但是,从泛型类继承的类确实在运行时知道它在继承中使用的类型参数。那就是:
// <String> is erased at run time.
new ArrayList<String>();
// <String> is preserved at run time, as part of the class's information.
class MyList extends ArrayList<String> { }
// A class identical to MyList is created, except without the name, and an instance of that class is created.
new ArrayList<String>(){};