달력

2

« 2025/2 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
2011. 7. 17. 17:05

와일드카드 캡쳐 JAVA이야기2011. 7. 17. 17:05

일반적으로 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 ?와 호환되지 않으므로 이 호출은 허용되지 않음. 

'JAVA이야기' 카테고리의 다른 글

클래스 확장과 제네릭 타입  (0) 2011.07.17
제거와 원시타입  (0) 2011.07.17
제네릭 메소드 호출과 타입 추정  (0) 2011.07.16
제네릭 타입  (0) 2011.07.16
[java] 배열과 타입  (0) 2011.07.16
:
Posted by НooпeУ


Code Start Code End