2010-04-23 39 views
6

Loại đối số chính xác cho phương thức addAll (..) trong bộ sưu tập Java là gì? Nếu tôi làm như sau:Generics java và phương thức addAll

List<? extends Map<String, Object[]>> currentList = new ArrayList<Map<String, Object[]>>(); 
Collection<HashMap<String, Object[]>> addAll = new ArrayList<HashMap<String, Object[]>>(); 
// add some hashmaps to the list.. 
currentList.addAll(addAll); 

Tôi hiểu tôi cần phải khởi tạo cả hai biến. Tuy nhiên, tôi nhận được lỗi biên dịch (từ nhật thực):

Multiple markers at this line 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments (List<capture#2-of ? extends 
    Map<String,Object[]>>) 
    - The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments 
    (Collection<HashMap<String,Object[]>>) 

tôi đang làm gì sai?

+1

Bạn có thể chỉnh sửa để hiển thị các khai báo của mình cho cả 'currentList' và 'newElements' không? – elduff

+0

Tôi nghĩ 'newElements' được cho là 'addAll' tôi đã sửa mã. – Jherico

Trả lời

7

Bạn chỉ có thể chèn các bản sao của T vào một số List<T>.

Loại List<? extends Map<X,Y>> là viết tắt của danh sách không xác định loại T trong đó extends Map<X,Y>. Ví dụ, nó có thể đứng cho một List<LinkedHashMap<X,Y>>. Rõ ràng, bạn không thể chèn một số HashMap<X,Y> thông thường vào danh sách như vậy.

Bạn có thể muốn:

List<Map<String, Object[]>> currentList; 

Hoặc nếu bạn muốn được thực sự linh hoạt bạn có thể làm:

List<? super Map<String, Object[]>> currentList; 

Trong đó sẽ cho phép bạn làm những việc điên rồ như:

currentList = new ArrayList<Map<? super String, ? extends Object[]>>(); 

Bạn cũng có thể muốn đọc Câu hỏi thường gặp về Generics của Angelika Langer, đặc biệt là the section about wildcards.

0

Câu hỏi của bạn về cơ bản nắm này:

public static <T extends Collection<?>> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

này sẽ thất bại với chủ yếu các lỗi tương tự như bạn mô tả. Hãy thử một cái gì đó dọc theo những dòng này để sửa chữa nó.

public static <T extends Collection<Y>, Y> void foo(T t) { 
T x = null; 
x.addAll(t); 
} 

Ngoài ra, trong ví dụ của bạn ở trên, bạn có thể thay đổi

List<? extends Map<String, Object[]>> currentList; 

để

List<Map<String, Object[]>> currentList; 

Generics được lông khá nhanh chóng nếu bạn cố gắng để bắt đầu đi xung quanh loại không xác định.

1

Bạn không thể gọi bất kỳ phương pháp nào có thuộc tính chung trên danh sách như vậy. Về cơ bản, những gì ? extends Foo nói là "cái gì đó kéo dài Foo", nhưng bạn không biết cái gì đó là gì. Khi loại đó được trả lại, bạn có thể nói rằng giá trị trả lại là Foo hoặc một số loại phụ. Nhưng đối với bất kỳ giá trị cụ thể nào bạn không thể khớp với giá trị ? extends Foo chung chung.

Nói tóm lại: bạn cần phải thay đổi currentList khai hoặc cast nó để List (mà không generics) và sống với một cảnh báo hoặc (nếu bạn biết những gì bạn đang làm) ngăn chặn nó.

8

Thay thế extends theo super.

addAll() chính nó cần một đối số ? extends T và điều đó sẽ không hoạt động khi T? extends Map<K, V>. Với thay đổi, nó sẽ có hiệu lực ? extends ? super Map<K, V>.

Tuy nhiên, tốt hơn là chỉ cần xóa ? extends (hoặc ? super). Nó không cần thiết trong trường hợp cụ thể này. Chỉ cần sử dụng List<Map<String, Object[]>>. Sau đó, addAll() sẽ có hiệu lực là ? extends Map<String, Object[]>>.

+0

tại sao thậm chí khai báo 'currentList' là' List > ', và không chỉ' List > '? phần này của anh ta dường như không cần thiết. –

+0

@matt: Đó cũng là những gì tôi đã nói trong đoạn cuối :) – BalusC

6

chỉ cần nhớ:

cho <? extends ...>, bạn không thể đặt mọi thứ (trừ null) vào nó

cho <? super ...>, bạn không thể có được những điều (trừ đối tượng) ra khỏi nó

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