使用typeliteral在guice中注入泛型,但是typeliteral构造函数受到保护

时间:2017-10-26 19:27:26

标签: java generics dependency-injection guice

我已经开始学习guice并偶然发现使用guice注入泛型类型。网中的所有解决方案似乎都使​​用new TypeLiteral<Generic<Type>>(){}之类的东西。但是,当我尝试这样做时,它表明TypeLiteral的构造函数受到保护。如何使用TypeLiteral.get()执行通用注入?示例代码:

public interface Repository<T> {
  void save(T item);
  T get(int id);
}

public StringRepository implements Repository<String> {
  @Override
  public void save(String item) {
    // do saving

  }
 @Override
 public String get(int id) {
   // get item and return
   return item;
 }
}

public MyModule extends AbstractModule{
   @Override
   public void configure() {
      ....
    TypeLiteral<Repository<String>> typeLiteral =
                  TypeLiteral.get((Repository<String>.class));//does not work

    //does not work either because constructor is protected
    bind(new TypeLiteral<Repository<String>>(){}).to(StringRepository.class); 

}

}

Screenshot of my problem

1 个答案:

答案 0 :(得分:3)

您的文字说new TypeLiteral<Generic<Type>>(){}。您的屏幕截图显示new TypeLiteral<Generic<Type>>()。第一个是{},第二个没有。这些花括号是关键的 - 它们将表达式从创建TypeLiteral的新实例改为创建 TypeLiteral的匿名子类并创建该子类的实例。

这是解决泛型类型擦除的必要条件。为了使TypeLiteral能够实现其目的,它必须在运行时知道泛型类型参数是什么。类型擦除意味着泛型类的简单实例在运行时不知道它的类型参数是什么。但是,从泛型类继承的类确实在运行时知道它在继承中使用的类型参数。那就是:

// <String> is erased at run time.
new ArrayList<String>();

// <String> is preserved at run time, as part of the class's information.
class MyList extends ArrayList<String> { }

// A class identical to MyList is created, except without the name, and an instance of that class is created.
new ArrayList<String>(){};
相关问题