Guice Bind Универсальные типы - PullRequest
0 голосов
/ 04 июня 2018

есть ли способ связать универсальные типы следующего вида:

public interface A<T extends Number> {
  void print(T t);
}

public class B implements A<Integer> {
  @Override
  public void print(Integer i) {
    System.out.println(i);
  }
}

public class C implements A<Double> {
  @Override
  public void print(Double d) {
    System.out.println(d);
  }
}

как я могу точно связать вышеуказанный интерфейс и его реализации (используя TypeLiteral?), Чтобы я мог создать типизированныйэкземпляр по какому-либо условию?

class Main {
  public static void main(String[] args) {
    A a1 = Guice.createInjector(new MyModule()).getInstance( ??? );
    a1.print(1); //will print 1

    A a2 = Guice.createInjector(new MyModule()).getInstance( ??? );
    a2.print(1.0); //will print 1.0
  }

}

как MyModule должен выглядеть?

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Вы можете создавать методы провайдера, не используя TypeLiteral<A<Integer>> в определении.

class MyModule extends AbstractModule {
  @Provides
  @Singleton
  A<Integer> provideAOfInteger() {
    return new B();
  }
}

И вы также можете использовать неявную привязку для доступа к A<Integer>:

class AOfIntegerHolder {
  @Inject A<Integer> aOfInteger;
}

Injector injector = Guice.createInjector(new MyModule());
A<Integer> a1 = injector.getInstance(AOfIntegerHolder.class).aOfInteger;

Прелесть Guice в том, что есть несколько способов сделать то, что вы хотите, и ни один не лучше другого: они просто разные;)

0 голосов
/ 04 июня 2018

То, что вам не хватает, это

Injector  injector = Guice.createInjector(new MyModule());
A a1 = injector.getInstance(Key.get(new TypeLiteral<A<Integer>>() {}));

И ваш MyModule

public static class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TypeLiteral<A<Integer>>() {}).toInstance(new B());
    }
}
...