泛型实例类型的Guice实例绑定

时间:2014-09-10 03:36:32

标签: java generics guice

我希望我的模块将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会抱怨&#34; T不能用作密钥;它没有完全指定&#34;。如何将泛型类绑定到我的模块创建的该类的实例?

2 个答案:

答案 0 :(得分:1)

我的解决方案与建议的副本不同。我需要保存类对象,以便正确地将类绑定到我选择的实例。

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);
  }
}

答案 1 :(得分:1)

无需使用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);
  }
}