java:将类作为依赖注入的参数传递

时间:2016-12-15 22:51:49

标签: java generics

我正在查看一个相对简单的代码块,该代码块命中数据库并将结果作为LinkedList返回。似乎很明显应该注入SQL,但后来我发现LinkedList也是一个不必要的依赖。

简化版如下:

public List<String> getStrings() {
    //Hard coded reference to LinkedList
    List<String> tmp = new LinkedList<String>();
    tmp.add("foo");
    return tmp;
}

我尝试重写它,让我在运行时指定List实现。

使用getStrings(LinkedList.class)调用getStrings(Class&lt; List&gt; listType)会给出有关该方法不适用的错误。以下工作正常:

public List getStrings(Class<? extends List> listType) throws InstantiationException, IllegalAccessException {
    List tmp = listType.newInstance();
    tmp.add("foo");
    return tmp;
}

public void caller() throws InstantiationException, IllegalAccessException {
    List stringList = getStrings(LinkedList.class);
}

然而,所有对List和tmp的引用都抱怨类型安全,因为它确实应该是List&lt;字符串&gt;。

在getStrings()中添加通用的工作正常:

public List<String> getStrings(Class<? extends List<String>> listType) throws InstantiationException, IllegalAccessException {
    List<String> tmp = listType.newInstance();
    tmp.add("foo");
    return tmp;
}

但更新的调用根本没有编译:

getStrings(LinkedList<String>.class);

以下作品,但给我一个未经检查的演员警告:

getStrings((Class<? extends List<String>>) LinkedList.class);

有没有正确的方法(tm)呢?

1 个答案:

答案 0 :(得分:2)

正如您所发现的,运行时反射与编译时泛型不能很好地混合。如果您正在使用Java 8,我建议采用更清洁,更安全的方法:

public List<String> getStrings(Supplier<List<String>> listSupplier) {
    List<String> tmp = listSupplier.get();
    tmp.add("foo");
    return tmp;
}

public void caller() {
    List<String> stringList = getStrings(LinkedList::new);
}