2010-04-23 6 views
6

Java 콜렉션에서 addAll (..) 메소드에 대한 올바른 유형의 인수는 무엇입니까? 내가 이런 식으로하면 :java generics 및 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); 

나는 두 변수를 모두 초기화해야한다는 것을 알고있다. 그러나 컴파일 오류가 발생합니다 (일식에서) :

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[]>>) 

무엇이 잘못 되었나요?

+1

'currentList'와 'newElements'둘 다에 대한 선언을 표시하도록 편집 할 수 있습니까? – elduff

+0

'newElements'가 'addAll'이되어야한다고 생각합니다. 코드를 수정했습니다. – Jherico

답변

7

삽입 할 수 있습니다 그것의 (객체 제외) 일을 얻을 수 없다 T의 인스턴스는 List<T>입니다.

유형은 List<? extends Map<X,Y>>알 수없는 유형 extends Map<X,Y>T의 목록을 의미합니다. 예를 들어, List<LinkedHashMap<X,Y>> 일 수 있습니다. 물론, 보통의 HashMap<X,Y>을 그러한 목록에 삽입 할 수는 없습니다.

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

을 또는 당신이 정말 유연하고 싶다면 당신은 할 수 :

당신은 아마 원하는

currentList = new ArrayList<Map<? super String, ? extends Object[]>>(); 
: 당신은 미친 듯이 일을 할 수 있도록 할

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

Angelika Langer의 Generics FAQ, 특히 the section about wildcards을 읽어 볼 수도 있습니다.

0

귀하의 질문은 기본적으로 다음과 같이 요약 될 : 당신이 설명하는대로 이것은 본질적으로 같은 오류와 함께 실패합니다

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

. 이 선을 따라 뭔가를 시도해 수정하십시오. 당신이 주변에 지정되지 않은 유형의 전달을 시작하려고하면

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

또는 귀하의 예제에서 당신은

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

제네릭 털이 꽤 빨리 도착에

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

을 바꿀 수 위.

1

이러한 목록에 일반 속성이있는 메소드를 호출 할 수 없습니다. 기본적으로 ? extends Foo이 말하는 것은 "Foo을 확장하는 무언가"라고되어 있지만 그 무엇이 무엇인지 모릅니다. 해당 유형이 반환되면 반환 값은 Foo 또는 일부 하위 유형이라고 말할 수 있습니다. 그러나 주어진 값에 대해서는 ? extends Foo generic과 일치 할 수는 없습니다.

한마디로

: 당신은 그것을 억제 currentList 선언 또는 ( 제네릭없이 ) List에 그것을 캐스트를 변경하고 (당신은 당신이 무엇을하고 있는지 알고있는 경우) 경고 또는 함께 생활해야합니다.

8

extendssuper으로 바꿉니다.

addAll()? extends T 인수를 취하며 T? extends Map<K, V> 일 때 작동하지 않습니다. 변경하면 효과적으로 ? extends ? super Map<K, V>이됩니다.

그래도 더 나은 것은 단지 ? extends (또는 ? super)을 제거하는 것입니다. 이 특별한 경우에는 불필요합니다. List<Map<String, Object[]>>을 사용해주세요. 그러면 addAll()은 실질적으로 ? extends Map<String, Object[]>>이됩니다.

+0

왜'currentList'를'List >'뿐만 아니라'List >'? 코드의이 부분은 나에게 불필요한 것처럼 보입니다. –

+0

@matt : 마지막 단락에서 말한 내용이기도합니다. :) – BalusC

6

은 기억 <? extends ...>를 들어,

<? super ...> 위해로 (널 제외) 물건을 넣을 수 없습니다

, 당신은 당신 만