Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 535
Ry. Avatar asked Mar 19 '09 14:03

Ry.


People also ask

How do you cast a List in Java?

Try the following: List<TestA> result = new List<TestA>(); List<TestB> data = new List<TestB>(); result. addAll(data);

Can you cast to generic in Java?

The Java compiler won't let you cast a generic type across its type parameters because the target type, in general, is neither a subtype nor a supertype.

How do I cast a List of objects?

you can always cast any object to any type by up-casting it to Object first. in your case: (List<Customer>)(Object)list; you must be sure that at runtime the list contains nothing but Customer objects.


1 Answers

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() 
like image 117
Jon Skeet Avatar answered Oct 09 '22 02:10

Jon Skeet