2009-03-19 15 views
26

perche il seguente frammento:Come posso trasmettere una lista usando i generici in 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; 
} 

L'istruzione return fa un casting che non può essere compilato. Come posso convertire la lista myPojos nell'elenco più generico, senza dover passare per ogni elemento della lista?

Grazie

risposta

41

cambiare il metodo per utilizzare un carattere jolly:

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

    return myPojos; 
} 

Questo eviterà che il chiamante di cercare di aggiungere altri implementazioni dell'interfaccia alla lista. In alternativa, si può solo scrivere:

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

Come discusso nei commenti:

  • Restituzione di collezioni con caratteri jolly può essere scomodo per chi chiama
  • Di solito è meglio usare le interfacce invece di tipi concreti per il ritorno tipi. Quindi la firma suggerita sarebbe probabilmente uno dei:

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

La seconda soluzione è migliore IMHO. Restituire le wild card è generalmente considerato una cattiva pratica, b/c limita il codice client. In questo caso con ArrayList è possibile solo leggere dall'elenco e non è possibile aggiungervi nulla. –

+0

Questo potrebbe essere ciò che volevamo, ovviamente - semplicemente non lo sappiamo. (Si deve quasi certamente utilizzare Elenco invece di ArrayList pure, o forse solo Iterable o Collection .) –

+1

+1 per utilizzare altri tipi generici (es Elenco , Collection ). Ma il ritorno dei caratteri jolly è raramente quello che vuoi. Se sei incline all'immutabilità, ci sono modi migliori per farlo. Naftalin e Wadler parlano di questo in "Java Generics and Collections". –

4

Si dovrebbe fare:

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

In questo caso, lo farei in questo modo:

public ArrayList<MyInterface> getMyInterfaces() { 

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

    return myPojos; 
} 

MyPojo è di tipo MyInterface (come implementa l'interfaccia). Ciò significa che puoi semplicemente creare la lista con l'interfaccia di cui hai bisogno.

0

Tenta di utilizzare interfacce ovunque, tranne che quando si costruiscono le istanze, e voi problemi andrà via:

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

    return myInterfaces; 
} 

Come altri hanno già detto, l'uso di MyInterface risolve il problema. È inoltre preferibile utilizzare l'interfaccia Elenco anziché ArrayList per tipi di ritorno e variabili.

+0

L'uso di List non è ciò che lo risolve comunque - è l'uso di MyInterface invece di MyPojo come argomento type. –

+0

Sì, era fuorviante, ora risolto. – starblue

24

Scegliere il tipo giusto dall'inizio è il migliore, tuttavia per rispondere alla domanda è possibile utilizzare la cancellazione del tipo.

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

+3

IMO, questa dovrebbe essere la risposta, poiché in alcuni casi, semplicemente non è possibile aggiungere gli elementi a una raccolta del tipo base: pensa al set di risultati JPA delle query, hai un elenco di entità JPA e se ti piace restituire questa lista al chiamante utilizzando un'interfaccia di astrazione sopra l'entità (agnostico di persistenza), il consiglio di Peter è * il * modo –

Problemi correlati