일반적으로 List<T>가 기대되는 곳에 List<?>를 사용할 수는 없다. 왜냐하면 와일드카드가 표현하는 실제 타입은 T와 호환되느지는 알 수 없기 때문이다. 그래서 와일드 카드와 제네릭 메소드의 타입 변수 사이에 존재하는 간격을 다루는 특수한 규칙이 존재한다.
이 규칙은 알려지지 않으느 제네릭 타입 X를 와일드카드의 캡처로 표현할 수 있게 해주며 호출 시 에 T가 X라고 추정할 수 있게 해준다.
캡처 변환을 적용하기 위해서는 와일드카드와 관련된 타입 변수 사이애 유일한 매핑만이 존재해야한다.
1. 캡쳐변환은 한 개 이상의 메소드 매개변수에 타입 매개변수를 사용했을 때는 적용할 수 없다.
static <T> List<T> merge(List<T> first, List<T> second){}
first와 second의 타입인자로 List<?>를 전달 할 수 없다. 이 메소드를 호출하면 첫 번째 인자의 타입을 X로, 두번째 인자의 타입을 Y로 교체 그리고 나서 T가 유일한지를 파악할 것이다. 하지만 X와Y가 동일한지 보증할 수 없다.
2. 캡처 변환은 타입 변수가 제네릭 타입의 최상위에 정의되어 있는 경우에만 적용할 수 있다.
static <T> void processList(List<List<T>> list){}
메소드 인자 타입에 List<List<?>> 을 주어 호출했다고 가정하자.
메소드는 List가 모두 동일한 타입의 요소이기를 바라지만, List<List<String>>, List<List<Object>>가 될 수도 있으므로 유일함을 보증하지 못한다.
3. 와일드카드의 타입을 알 필요가 있는 곳에는 와일드 참조를 사용할 수 없다.
static <T> void addToList(List<T> list, T t){}
List<?> 타입의 참조를 전달할 수 없다. 왜냐하면 T의 추정 타입은 capture of ? T의 추정타입은 유일하게 정의되지 않을 것.
List<?> lists = new ArrayList<String>();
lists.add("hello"); //compile error
와일드카드 참조 lists가 사용되었을 때 list의 타입이 List<capture of ?>이다.
String은 capture of ?와 호환되지 않으므로 이 호출은 허용되지 않음.
이 규칙은 알려지지 않으느 제네릭 타입 X를 와일드카드의 캡처로 표현할 수 있게 해주며 호출 시 에 T가 X라고 추정할 수 있게 해준다.
캡처 변환을 적용하기 위해서는 와일드카드와 관련된 타입 변수 사이애 유일한 매핑만이 존재해야한다.
1. 캡쳐변환은 한 개 이상의 메소드 매개변수에 타입 매개변수를 사용했을 때는 적용할 수 없다.
static <T> List<T> merge(List<T> first, List<T> second){}
first와 second의 타입인자로 List<?>를 전달 할 수 없다. 이 메소드를 호출하면 첫 번째 인자의 타입을 X로, 두번째 인자의 타입을 Y로 교체 그리고 나서 T가 유일한지를 파악할 것이다. 하지만 X와Y가 동일한지 보증할 수 없다.
2. 캡처 변환은 타입 변수가 제네릭 타입의 최상위에 정의되어 있는 경우에만 적용할 수 있다.
static <T> void processList(List<List<T>> list){}
메소드 인자 타입에 List<List<?>> 을 주어 호출했다고 가정하자.
메소드는 List가 모두 동일한 타입의 요소이기를 바라지만, List<List<String>>, List<List<Object>>가 될 수도 있으므로 유일함을 보증하지 못한다.
3. 와일드카드의 타입을 알 필요가 있는 곳에는 와일드 참조를 사용할 수 없다.
static <T> void addToList(List<T> list, T t){}
List<?> 타입의 참조를 전달할 수 없다. 왜냐하면 T의 추정 타입은 capture of ? T의 추정타입은 유일하게 정의되지 않을 것.
List<?> lists = new ArrayList<String>();
lists.add("hello"); //compile error
와일드카드 참조 lists가 사용되었을 때 list의 타입이 List<capture of ?>이다.
String은 capture of ?와 호환되지 않으므로 이 호출은 허용되지 않음.
'JAVA이야기' 카테고리의 다른 글
클래스 확장과 제네릭 타입 (0) | 2011.07.17 |
---|---|
제거와 원시타입 (0) | 2011.07.17 |
제네릭 메소드 호출과 타입 추정 (0) | 2011.07.16 |
제네릭 타입 (0) | 2011.07.16 |
[java] 배열과 타입 (0) | 2011.07.16 |