Java 使用 Guice 注入泛型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2581137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Injecting generics with Guice
提问by paradigmatic
I am trying to migrate a small project, replacing some factories with Guice (it is my first Guice trial). However, I am stuck when trying to inject generics. I managed to extract a small toy example with two classes and a module:
我正在尝试迁移一个小项目,用 Guice 替换一些工厂(这是我的第一次 Guice 试用)。但是,我在尝试注入泛型时被卡住了。我设法提取了一个带有两个类和一个模块的小玩具示例:
import com.google.inject.Inject;
public class Console<T> {
private final StringOutput<T> out;
@Inject
public Console(StringOutput<T> out) {
this.out = out;
}
public void print(T t) {
System.out.println(out.converter(t));
}
}
public class StringOutput<T> {
public String converter(T t) {
return t.toString();
}
}
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(StringOutput.class);
bind(Console.class);
}
public static void main(String[] args) {
Injector injector = Guice.createInjector( new MyModule() );
StringOutput<Integer> out = injector.getInstance(StringOutput.class);
System.out.println( out.converter(12) );
Console<Double> cons = injector.getInstance(Console.class);
cons.print(123.0);
}
}
When I run this example, all I got is:
当我运行这个例子时,我得到的是:
Exception in thread "main" com.google.inject.CreationException: Guice creation errors:
线程“main”com.google.inject.CreationException 中的异常:Guice 创建错误:
1) playground.StringOutput<T> cannot be used as a key; It is not fully specified.
at playground.MyModule.configure(MyModule.java:15)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
at com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152)
at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105)
at com.google.inject.Guice.createInjector(Guice.java:92)
I tried looking for the error message, but without finding any useful hints. Further on the Guice FAQ I stumble upon a question about how to inject generics. I tried to add the following binding in the configure
method:
我尝试查找错误消息,但没有找到任何有用的提示。在 Guice FAQ 上,我偶然发现了一个关于如何注入泛型的问题。我尝试在configure
方法中添加以下绑定:
bind(new TypeLiteral<StringOutput<Double>>() {}).toInstance(new StringOutput<Double>());
But without success (same error message).
但没有成功(相同的错误消息)。
Can someone explain me the error message and provide me some tips ? Thanks.
有人可以向我解释错误消息并提供一些提示吗?谢谢。
采纳答案by ColinD
I think the specific issue you're seeing is probably because of the bind(Console.class)
statement. It should use a TypeLiteral
as well. Or, you could just bind neither of those and JIT bindings will take care of it for you since both of the types involved here are concrete classes.
我认为您看到的具体问题可能是因为该bind(Console.class)
声明。它也应该使用 a TypeLiteral
。或者,您可以不绑定任何一个,JIT 绑定将为您处理它,因为这里涉及的两种类型都是具体类。
Additionally, you should retrieve the Console
with:
此外,您应该使用以下方法检索Console
:
Console<Double> cons =
injector.getInstance(Key.get(new TypeLiteral<Console<Double>>(){}));
Edit:You don't need to bind to an instance just because you're using a TypeLiteral
. You can just do:
编辑:您不需要仅仅因为使用TypeLiteral
. 你可以这样做:
bind(new TypeLiteral<Console<Double>>(){});
Of course, like I said above you could just skip that in this case and retrieve the Console
from the injector using a Key
based on the TypeLiteral
and the binding would be implicit.
当然,就像我上面说的那样,在这种情况下,您可以跳过它并Console
使用Key
基于的从注入器中检索TypeLiteral
并且绑定将是隐式的。