배열과 달리 제네릭에서는 공변성/반공변성 을 지원하지 않는다.
// 공변성
Object[] Covariance = new Integer[10];
// 반공변성
Integer[] Contravariance = (Integer[]) Covariance;
// 공변성
ArrayList<Object> Covariance = new ArrayList<Integer>();
// 반공변성
ArrayList<Integer> Contravariance = new ArrayList<Object>();
이를 극복하고자 한 것이 와일드카드
class MyArrayList<T> {
Object[] element = new Object[5];
int index = 0;
// 외부로부터 리스트를 받아와 매개변수의 모든 요소를 내부 배열에 추가하여 인스턴스화 하는 생성자
public MyArrayList(Collection<? extends T> in) {
for(T elem : in) {
element[index++] = elem;
}
}
// ...
}
와일드카드는 이미 만들어진 제네릭 클래스나 메서드를 사용할때 이용하는 것으로 봐야된다.
class Sample<? extends T> { // ! Error
}
이런 식으로 쓰는게 아니라는 점
List<? extends U>
상위가 제한이다.
꺼내는 건 U만 저장은 불가하다.
List<? super U>
하위가 제한이다.
꺼내는건 Object만 저장은 U이하가 가능하다.
List<?>
제한이 없다.
꺼내는 건 Object만 저장은 불가( null만 저장가능하다. )
상위 제한으로만 꺼낼 수 있고 하위 제한까지만 저장이 가능하다.
다운 캐스팅으로 인한 런타임 에러를 주의하자.