2012-03-09 5 views
3
나는 다음과 같은 목록을 인스턴스화

으로 목록에 추가 할 수 없습니다. 컴파일러 오류가 발생합니다. 그러나 다음 작품 :제네릭은 무제한의 와일드 카드

List<? super Integer> someList = new ArrayList<Object>(); 
someList.add(11); 

나는 당신이 억제 할 와일드 카드가 아닌 경계 와일드 카드를 포함하는 컬렉션에 개체를 추가 할 수 있음을 알고 있습니다.

그러나 위의 기능이 작동하지 않는 이유는 무엇입니까? 개체가 정수의 상위 유형이므로 개체를 추가 할 수없는 이유는 무엇입니까?

답변

4

그 목록에는 Integer의 수퍼 유형 인 것으로 선언되며, 목록에는 Integer의 수퍼 유형 인 모든 것을 포함 할 수 없습니다. 즉, 컴파일러의 경우 List<Integer>, List<Number> 또는 List<Object> 일 수 있지만 어느 항목인지 모르기 때문에 목록에 아무 것도 추가 할 수 없습니다. 안전하게 추가 할 수있는 유일한 것은 Integer입니다. List가 잠재적으로 보유 할 수있는 모든 유형의 부속 유형이 될 수 있기 때문입니다. 환언

상기 ? 는 하나 입력하지 어떤 유형을 나타낸다. 그것은 분명하지 않지만 중요한 구분입니다.

+0

첫 번째 문장을 잘 모르겠습니다. 그래서, Objects *와 * Integers의리스트가 될 수 없습니다. 단 하나의 유형? 그러나 정수의 마지막 부분에 응답하여 정수를 목록에 추가 할 수 있습니다. – Joeblackdev

+1

아 맞아. 내 잘못이야. Integer는 경계이므로 List가 될 수있는 모든 유형의 하위 유형이 될 수 있으므로 Integer를 추가 할 수 있습니다. 하지만 Integer의 수퍼 유형 임에도 불구하고 Number와 같은 다른 유형은 사용할 수 없습니다. 첫 번째 문장에 관해서는 생각해 보았습니다. 일반적인 와일드 카드는 목록에 여러 유형의 개체가 포함될 수 있음을 의미하지는 않습니다. 목록에 알 수없는 유형의 객체가 있음을 의미합니다. 예를 들어, 해당 유형 *이 Number 일 수 있기 때문에 목록에 객체를 추가하는 것은 불법입니다. –

+0

이 의견에 따라 답변을 업데이트했습니다. –

4

변수 someList의 경우 모든 컴파일러/언어에서 작동해야하는 정적 유형은 List<? super Integer>입니다. List<Integer>에서 할당되었을 수 있습니다. 분명히 new Object()List<Integer>에 추가하고 싶지는 않습니다.

당신은 List<? super Integer>null을 추가 할 수 있으며 일반 유형을 캡처 다른 방법으로 목록을 통과 할 수 있으므로 (예 : Collections.shuffle, 같은 방법) 목록 주위에 대한 참조를 이동할 수 있습니다.

+0

아, 네 말이 맞아. 나는 덧붙일 'null'을 놓쳤다. –

+0

나는이 이상한 것을 발견한다.어쨌든 Integer와 동일한 상속 계층에 있으므로 Object를 추가 할 수 없습니까? 또는 이것이 주관적인 가정입니까 - 왜 "정수 목록"에 개체를 추가합니까? – Joeblackdev

+0

문제는'List list = new List ()'이라면, 실제로는 List''' 인리스트에'Object'를 추가 할 수 없습니다. 그것은 완벽하게 객관적입니다. –

1

List<? super Integer>은 수퍼 유형이 Integer (이는 의미가 없음)이 아닌 목록이지만 구체적인 유형은 수퍼 유형 인 알 수없는 요소 유형 Integer입니다. 따라서 컴파일러는 추가 할 요소가 올바른 구체화 유형인지 판단 할 기회가 없습니다.

요소 유형에 와일드 카드가있는 모든 컬렉션은 확장 할 수 없지만 수정할 수 있습니다 (요소를 제거하거나 전체 목록을 지울 수 있음).

1

컴파일러가 someList.add(new Object())이되면 someList을 인스턴스화하는 방법을 기억하지 못합니다. 컴파일러에있는 모든 정보는 someList이 선언 된 방법입니다 (예 : List<? super Integer> someList). 당신도

someList = new ArrayList<Object>() 

또는

someList = new ArrayList<Integer>() 

에 의해 someList를 인스턴스화 할 수 있으며, 컴파일러가 인 일을 알고하지 않기 때문에, 따라서 컴파일러는 someList가 될 수 있기 때문에 당신이 someList.add(new Object())을 수행 할 수 없습니다 List<Integer>.