Я пытаюсь переместить маленький проект, заменяя некоторые фабрики 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);
}
}
То, когда я выполняю этот пример, все, что я получил:
Исключение в потоке "основной" 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)
Я пытался искать сообщение об ошибке, но не находя полезных подсказок. Далее на FAQ Guice я натыкаюсь на вопрос о том, как ввести дженерики. Я пытался включить следующую привязку configure
метод:
bind(new TypeLiteral<StringOutput<Double>>() {}).toInstance(new StringOutput<Double>());
Но без успеха (то же сообщение об ошибке).
Кто-то может объяснить меня сообщение об ошибке и предоставить мне некоторые подсказки?Спасибо.
Я думаю, что конкретная проблема, которую вы наблюдаете, вероятно, связана с утверждением bind(Console.class)
. Оно должно использовать TypeLiteral
. Или вы можете просто связать ни то, ни другое, и привязка JIT позаботится об этом за вас, поскольку оба типа, задействованные здесь, являются конкретными классами.
Кроме того, вы должны получить Console
с помощью:
Console<Double> cons =
injector.getInstance(Key.get(new TypeLiteral<Console<Double>>(){}));
Edit: Вам не нужно привязываться к экземпляру только потому, что вы используете TypeLiteral
. Вы можете просто сделать:
bind(new TypeLiteral<Console<Double>>(){});
Конечно, как я сказал выше, вы можете просто пропустить это в данном случае и получить Console
из инжектора, используя Key
на основе TypeLiteral
, и привязка будет неявной.