如何在 Java 中使用泛型转换列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/662508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:33:44  来源:igfitidea点击:

How can I cast a list using generics in Java?

javagenericscasting

提问by Ry.

Please consider the following snippet:

请考虑以下片段:

public interface MyInterface {

    public int getId();
}

public class MyPojo implements MyInterface {

    private int id;

    public MyPojo(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

}

public ArrayList<MyInterface> getMyInterfaces() {

    ArrayList<MyPojo> myPojos = new ArrayList<MyPojo>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return (ArrayList<MyInterface>) myPojos;
}

The return statement does a casting that doesn't compile. How can I convert the myPojos list to the more generic list, without having to go through each item of the list?

return 语句执行无法编译的转换。如何将 myPojos 列表转换为更通用的列表,而不必遍历列表的每个项目

Thanks

谢谢

采纳答案by Jon Skeet

Change your method to use a wildcard:

更改您的方法以使用通配符:

public ArrayList<? extends MyInterface> getMyInterfaces() {    
    ArrayList<MyPojo> myPojos = new ArrayList<MyPojo>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

This will prevent the caller from trying to add otherimplementations of the interface to the list. Alternatively, you could just write:

这将阻止调用者尝试将接口的其他实现添加到列表中。或者,你可以只写:

public ArrayList<MyInterface> getMyInterfaces() {
    // Note the change here
    ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

As discussed in the comments:

正如评论中所讨论的:

  • Returning wildcarded collections can be awkward for callers
  • It's usually better to use interfaces instead of concrete types for return types. So the suggested signature would probably be one of:

    public List<MyInterface> getMyInterfaces()
    public Collection<MyInterface> getMyInterfaces()
    public Iterable<MyInterface> getMyInterfaces()
    
  • 返回通配符集合对于调用者来说可能很尴尬
  • 对于返回类型,通常最好使用接口而不是具体类型。所以建议的签名可能是以下之一:

    public List<MyInterface> getMyInterfaces()
    public Collection<MyInterface> getMyInterfaces()
    public Iterable<MyInterface> getMyInterfaces()
    

回答by Jacob Schoen

You should be doing:

你应该这样做:

public ArrayList<MyInterface> getMyInterfaces() {   
   ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);    
   myPojos.add(new MyPojo(0));    
   myPojos.add(new MyPojo(1));    
   return myPojos;
}

回答by Tobias Langner

In this case, I would do it like this:

在这种情况下,我会这样做:

public ArrayList<MyInterface> getMyInterfaces() {

    ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

MyPojo ist of type MyInterface (as it implements the interface). This means, you can just create the List with the Interface you need.

MyPojo 是 MyInterface 类型的(因为它实现了接口)。这意味着,您可以使用您需要的接口创建列表。

回答by starblue

Try to use interfaces everywhere except when constructing instances, and you problems will go away:

尝试在任何地方使用接口,除了在构造实例时,你的问题就会消失:

public List<MyInterface> getMyInterfaces()
{
    List<MyInterface> myInterfaces = new ArrayList<MyInterface>(0);
    myInterfaces.add(new MyPojo(0));
    myInterfaces.add(new MyPojo(1));

    return myInterfaces;
}

As others have said already, the use of MyInterface fixes your problem. It is also better to use the List interface instead of ArrayList for return types and variables.

正如其他人已经说过的那样,使用 MyInterface 可以解决您的问题。对于返回类型和变量,最好使用 List 接口而不是 ArrayList。

回答by Peter Lawrey

Choosing the right type from the start is best, however to answer your question you can use type erasure.

从一开始就选择正确的类型是最好的,但是要回答您的问题,您可以使用类型擦除。

return (ArrayList<MyInterface>) (ArrayList) myPojos;

return (ArrayList<MyInterface>) (ArrayList) myPojos;