无需显式转换即可将通用列表传递给超类型

时间:2019-07-19 08:08:25

标签: java

我使用具有此方法的API:

public void doSomething(List<Object> list);

在应用程序方面,我们只有一个特定的类,即“ MyClass”,应该传递给此api方法。

因此,出于此限制,我创建了一个将调用API的方法:

public void myMethod(List<MyClass>list){
 api.doSomething(list);
}

当然,它无法编译,我不能使用通配符,因为我无法触摸api代码。现在,我手动将MyClass泛型强制转换为Object。

对此有更好的解决方案吗?

3 个答案:

答案 0 :(得分:2)

否,API定义为“错误” (如果要避免强制转换)。最佳的API定义可能是:

// *external* API
static class API {
    public void doSomething(List<? extends Object> list) {
        throw new IllegalStateException("not implemented");
    }
}

现在,您可以使用任何? extending Object进行呼叫:

List<String> xs = new ArrayList<>();

new API().doSomething(xs);

请注意,任何对象扩展Object,然后? extends Object是多余的。 API可以重写为:

public void doSomething(List<?> list)

但是通常,您会得到类似的东西:

public void doSomething(List<ApiDataModel> list)

然后,正确的方法又是:

public void doSomething(List<? extends ApiDataModel> list)

答案 1 :(得分:1)

做一些简单的事情怎么样?

public static void myMethod(List<MyClass> list) {
    doSomething(new ArrayList<>(list));
}

除非您要删除列表中的内容或将其添加到列表中,否则可以使用它。否则,由于您将实例化一个新列表,因此对该列表所做的任何更改都将丢失并且不会反映到您的list中,但是MyClass对象的各个元素上的更改将会丢失。

答案 2 :(得分:1)

您可以通过以下方式从列表创建列表:

public void myMethod(List<MyClass> list){
    List<Object> objectList = new ArrayList<>();
    objectList.addAll(list)
    api.doSomething(objectList);
}

或仅使用非通用类型转换(这将生成警告):

public void myMethod(List<MyClass> list){
    api.doSomething((List)list);
}