我希望我的模块将Parent的子类绑定到我创建的实例。
public class MyModule<T extends Parent> implements AbstractModule {
T myAwesomeInstance;
MyModule(String[] args, Class<T extends Parent> clazz) {
myAwesomeInstance = clazz.newInstance(); // catching exceptions and stuff ...
ArgumentParser.configure(myAwesomeInstance, args);
}
@Override
void configure() {
bind(new TypeLiteral<T>(){}).toInstance(myAwesomeInstance);
}
}
这段代码编译得很好,但当我尝试运行时,Guice会抱怨"T不能用作键;它没有完全指定"。如何将泛型类绑定到模块创建的类的实例?
无需使用TypeLiteral
,只需直接使用Key
即可。(如果你愿意的话,这给了你一个添加注释的机会。)
最好将构建实例推迟到单例时间,而不是模块实例化时。例如,你可以做:
public final class MyModule<T extends Parent> extends AbstractModule {
private final Key<T> key;
private final Provider<T> provider;
public MyModule(final Class<T> clazz, final String[] args) {
this.key = Key.get(clazz); // Or add an annotation if you feel like it
this.provider = new Provider<T>() {
@Override public T get() {
try {
T instance = clazz.newInstance();
// etc.
} catch (ReflectiveOperationException ex) {
// throw a RuntimeException here
}
}
};
}
@Override protected void configure() {
bind(key).toProvider(provider).in(Singleton.class);
}
}
我的解决方案与建议的重复方案不同。我需要保存类对象,以便将类正确绑定到我选择的实例。
public class MyModule<T extends Parent> implements AbstractModule {
T myAwesomeInstance;
Class<T> _clazz;
MyModule(String[] args, Class<T extends Parent> clazz) {
myAwesomeInstance = clazz.newInstance(); // catching exceptions and stuff ...
_clazz = clazz;
ArgumentParser.configure(myAwesomeInstance, args);
}
@Override
void configure() {
bind(TypeLiteral.get(_clazz)).toInstance(myAwesomeInstance);
}
}