2015-12-29 14 views
9

Giả sử tôi có hai lớp AB mở rộng A. Với phương pháp sau đây tôi có thể in một Collection của A hoặc một cái gì đó kéo dài A:<? mở rộng ...> tính độc quyền của các tham số phương thức?

private static void print(Collection<? extends A> collection) { 

    for (A element : collection) { 
     System.out.println(element); 
    } 

} 

Thật tuyệt vời, tôi có thể làm điều gì đó như:

public static void main(String[] args) { 

    List<A> l1 = new ArrayList<>(); 
    l1.add(new A()); 
    l1.add(new B()); 
    print(l1); 

    List<B> l2 = new ArrayList<>(); 
    l2.add(new B()); 
    l2.add(new B()); 
    print(l2); 

} 

Bây giờ câu hỏi của tôi là tại sao trong phương pháp của tôi main (hoặc ở một nơi khác) Tôi có thể viết điều này

List<? extends A> l3 = new ArrayList<>(); 

nhưng không phải điều này

l3.add(new A()); 
l3.add(new B()); 

Tôi hiểu tại sao tôi không thể thêm phiên bản A hoặc B vào l3. Nhưng tại sao tuyên bố đầu tiên dường như vô dụng được cho phép?

EDIT

tôi hỏi với các từ khác vì tôi nghĩ rằng câu hỏi của tôi là hiểu lầm.

Tôi có thể làm gì với danh sách trống List<? extends A> l3 = new ArrayList<>();? Tôi biết không thể thêm bất cứ điều gì vì loại danh sách không xác định.

Trả lời

-1

Câu trả lời là trong GENERICS, Loại AB không được biết cho đến khi chạy. Vì vậy, Java không thể khởi tạo chúng.

Để biết thêm xin vui lòng đọc Oracle Generics Documentation

6

List<? extends A> l3 nghĩa là l3có thể một List<A> hoặc nó có thể là một List<B>. <? extends A> có nghĩa là trình biên dịch không biết và không thể giả định một cách an toàn hơn bất kỳ điều gì.

Vì nó có thể làList<B>, l3.add(new A()) không an toàn. "? Kéo dài một" danh sách sẽ bị hỏng, vì nó sẽ không thực sự chỉ chứa các trường hợp của B.

+2

Nó thậm chí có thể được 'Danh sách ', nơi 'C' là cl khác ass mở rộng 'A'. Vì vậy, 'add (new B())' không an toàn. – Henry

+0

Vì vậy, nó không có ý nghĩa gì để viết 'Danh sách l3 = new ArrayList <>();' vì nó không thể sử dụng sau này? – cheb1k4

+0

Có thể sử dụng được. Bạn không thể thêm vào nó. – VGR

0

Generics không hiệp biến và không phải là A. Vì vậy, bạn không thể làm:

List<? extends A> l = new ArrayList<>(); 
l.add(new A()); 

vì những lý do tương tự như bạn không thể làm:

List<B> l = new ArrayList<>(); 
l.add(new A()); 

hay:

List<String> l = new ArrayList<>(); 
l.add(new Object()); 
+0

Tôi biết tôi không thể làm điều đó.Câu hỏi của tôi là tại sao tôi có thể viết 'Danh sách l3 = new ArrayList <>();' trong khi những gì bạn đề cập không được phép. – cheb1k4

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