Search code examples
javagenericscasting

How can I cast a list using generics in Java?


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?

Thanks


Solution

  • 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 other implementations 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()