2009-03-19 40 views
26

Hãy xem xét các đoạn mã sau:Làm thế nào tôi có thể truyền một danh sách bằng Generics trong 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ệnh return hiện một đúc mà không biên dịch. Làm cách nào để chuyển đổi danh sách myPojos thành danh sách chung chung hơn, mà không cần phải đi qua từng mục trong danh sách?

Cảm ơn

Trả lời

41

Thay đổi phương pháp của bạn để sử dụng một ký tự đại diệ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; 
} 

này sẽ ngăn chặn người gọi từ cố gắng để thêm triển khai khác của giao diện vào danh sách. Ngoài ra, bạn chỉ có thể viết:

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

Như đã thảo luận trong các ý kiến:

  • Trở sưu tập wildcarded có thể lúng túng cho người gọi
  • Nó thường tốt hơn để sử dụng giao diện thay vì các loại bê tông cho sự trở lại loại. Vì vậy, chữ ký đề nghị có lẽ sẽ là một trong số:

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

Giải pháp thứ hai tốt hơn một IMHO. Trả lại thẻ hoang dã thường được coi là thực hành xấu, b/c nó hạn chế mã khách hàng. Trong trường hợp này với ArrayList bạn chỉ có thể đọc từ danh sách và không thể thêm bất kỳ thứ gì vào danh sách đó. –

+0

Đó có thể là những gì mong muốn, tất nhiên - chúng tôi không biết. (Nó gần như chắc chắn nên sử dụng Danh sách thay vì ArrayList là tốt, hoặc có thể chỉ Iterable hoặc Bộ sưu tập .) –

+1

1 cho việc sử dụng các loại chung chung hơn (ví dụ Danh sách , Bộ sưu tập ). Nhưng trở về ký tự đại diện là hiếm khi những gì bạn muốn. Nếu bạn đang nghiêng về phía bất biến, có những cách tốt hơn để làm điều đó. Naftalin & Wadler nói về điều này trong "Java Generics and Collections". –

4

Bạn nên làm:

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

Trong trường hợp này, tôi sẽ làm điều đó như thế này:

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 loại MyInterface (khi nó thực hiện giao diện). Điều này có nghĩa, bạn chỉ có thể tạo Danh sách với Giao diện bạn cần.

0

Cố gắng sử dụng các giao diện ở khắp mọi nơi trừ khi xây dựng trường, và bạn vấn đề sẽ biến mất:

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

    return myInterfaces; 
} 

Như những người khác đã nói rồi, việc sử dụng các MyInterface sửa chữa vấn đề của bạn. Cũng tốt hơn khi sử dụng giao diện Danh sách thay vì ArrayList cho các kiểu trả về và các biến.

+0

Việc sử dụng Danh sách không phải là những gì sửa chữa ở đó mặc dù - đó là việc sử dụng MyInterface thay vì MyPojo làm đối số kiểu. –

+0

Vâng, điều đó đã gây hiểu lầm, đã sửa nó ngay bây giờ. – starblue

24

Chọn loại phù hợp ngay từ đầu là tốt nhất, tuy nhiên để trả lời câu hỏi của bạn, bạn có thể sử dụng loại xóa.

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

+3

IMO, đây sẽ là câu trả lời, vì trong một số trường hợp, bạn không thể thêm các mục vào bộ sưu tập kiểu cơ sở: suy nghĩ về kết quả JPA từ các truy vấn, bạn có danh sách các thực thể JPA và nếu bạn muốn trả lại danh sách này cho người gọi bằng cách sử dụng một số giao diện trừu tượng phía trên thực thể (kiên trì thuyết phục), lời khuyên của Peter là * cách * –

Các vấn đề liên quan