클래스 생성시 선언된 제네릭 문자를 사용하지 않고, 이미 선언된 제네릭 문자를 또다른 제네릭 문자로 재설명 하는 방법이 있습니다.
따라서 다음의 코드는 의미상 조금 다릅니다.
class Generic<T>{
public void put(Generic<Z> g){}
public <V> void put_2(V g){} // V로 재설명.
}
따라서, 다음과 같이 복잡한 제네릭 타입에 대한 설명을 앞에 써 줄 수 있습니다.
public static void printAll(ArrayList<? extends Unit> list) {}
public static <Z extends Unit> void printAll(ArrayList<Z> list){} // 위의 코드와 동일.
이것을 이용해 1편에 소개되었던 호환성 판별 불가에 관한 오류를 회피할 수 있습니다.
다시 한번 예의 그 코드를 보면 이렇습니다.
class BigBox<T>{
T element;
public T get(){
return element;
}
public void put(T element){
this.element = element;
}
public void unbox(BigBox<?> box) {
System.out.println(box.get());
}
public void rebox(BigBox<?> box) {
box.put(box.get()); // 호환성 에러
}
}
위의 코드를 해결하기 위해 저자가 캡쳐도우미라 일컫은 메소드, reboxHelper()메소드를
이용 해보겠습니다.
class BigBox<T>{
T element;
public T get(){
return element;
}
public void put(T element){
this.element = element;
}
public void unbox(BigBox<?> box) {
System.out.println(box.get());
}
public void rebox(BigBox<?> box) {
box.reboxHelper(box);
}
public <Z>void reboxHelper(BigBox<Z> box){ // Z로 재설명
box.put(box.get());
}
}
저자는 이것을 이렇게 설명하고 있습니다.
"캡처 도우미 비법은 와일드카드를 다루는 컴파일러의 한계를 우회하기 위한 것이다.
rebox()가 reboxHelper()를 호출할 때, box 매개변수는 알려지지 않은 T에 대한 Box<T>임이 분명하므로 그 메서드 호출이 안전하다는 것을 알고 있다. 메서드 시그너처(signature)에 소개된 타입 매개변수
V는 다른 타입 매개변수에 종속되지 않으므로, 이는 어떠한 알려지지 않은 타입을 가리킬 수 있다. 따라서 알려지지 않은
T에 대한 Box<T>는 또한 알려지지 않은 V에 대한 Box<V>일 수도 있다"또한,
"이제
reboxHelper() 내 box.get()의 표현은 더 이상 Object 타입을 갖는 것이 아니라 타입 V를 가진다. 이로써 V를 Box<V>.put()으로 넘길 수 있다."YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST





