2009-03-19 17 views
26

Por favor, considere el siguiente fragmento:¿Cómo puedo lanzar una lista usando genéricos en Java?

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; 
} 

La sentencia return hace un casting que no compila. ¿Cómo puedo convertir la lista myPojos a la lista más genérica, sin tener que pasar por cada elemento de la lista?

Gracias

Respuesta

41

cambiar su método de usar un comodín:

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

    return myPojos; 
} 

Esto evitará que la persona que llama se trata de añadir otros implementaciones de la interfaz a la lista. Alternativamente, usted podría escribir:

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; 
} 

Como se discutió en los comentarios:

  • que vuelven colecciones comodín puede ser incómodo para las personas que llaman
  • Por lo general es mejor utilizar las interfaces en lugar de tipos concretos de la devolución tipos. Por lo que la firma sugerido probablemente sería uno de:

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

La segunda solución es mejor que en mi humilde opinión. La devolución de comodines generalmente se considera una mala práctica, porque restringe el código del cliente. En este caso con ArrayList solo puede leer de la lista y no puede agregarle nada. –

+0

Eso puede ser lo que se quiere, por supuesto, simplemente no lo sabemos. (Se debe casi seguro que utilizar la lista en lugar de ArrayList también, o, posiblemente, sólo Iterable o Colección .) –

+1

1 para el uso de los tipos más genéricos (por ejemplo, la lista , Colección ). Pero devolver comodines rara vez es lo que quieres. Si te estás inclinando hacia la inmutabilidad, hay mejores formas de hacerlo. Naftalin y Wadler hablan sobre esto en "Java Generics and Collections". –

4

Usted debe hacer:

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

En este caso, lo haría así:

public ArrayList<MyInterface> getMyInterfaces() { 

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

    return myPojos; 
} 

MyPojo es de tipo MyInterface (ya que implementa la interfaz). Esto significa que puede crear la Lista con la Interfaz que necesita.

0

Trate de usar interfaces en todas partes excepto en la construcción de instancias, y vosotros problemas va a desaparecer:

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

    return myInterfaces; 
} 

Como otros han dicho ya, el uso de MyInterface solucione el problema. También es mejor usar la interfaz List en lugar de ArrayList para los tipos y variables de devolución.

+0

El uso de List no es lo que lo soluciona allí, es el uso de MyInterface en lugar de MyPojo como argumento de tipo. –

+0

Sí, eso fue engañoso, lo arregló ahora. – starblue

24

Elegir el tipo correcto desde el principio es lo mejor; sin embargo, para responder a su pregunta, puede utilizar el borrado de tipo.

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

+3

IMO, esta debería ser la respuesta, ya que en algunos casos, simplemente no puede agregar los elementos a una colección del tipo base: piense en el conjunto de resultados de JPA a partir de consultas, tiene una lista de entidades JPA y si desea devuelva esta lista a la persona que llama usando alguna interfaz de resumen por encima de la entidad (agnóstico de persistencia), el consejo de Peter es * el * camino –