Templete
, Typescript의 Generic
과 비슷하다.Stack<T>
, Map<T, K>
등이 있다Stack<?> q = new ArrayDeque();
특정 타입을 기준으로 상한 범위와 하한 범위를 지정하는 와일드 카드.
상황을 이해하기 위해 다음과 같이 3가지 클래스가 존재한다고 가정.
class MyGrandParent {}
class MyParent extends MyGrandParent {}
class MyChild extends MyParent {}
class AnotherChild extends MyParent {}
void printCollection(Collection<? extends MyParent> c) {
for( MyChild e : c ) { soutp(e); } // 컴파일 오류
for( MyParent e : c ) { soutp(e); } // OK
for( MyGrandParent e : c ) { soutp(e); } // OK
for( Object e : c ) { soutp(e); } // OK
}
extends
를 사용해서 와일드카드 타입의 최상위 타입을 정의함으로써 상한 경계를 결정<? extends MyParent>
로 가능한 타입은 MyParent와 미지의 모든 MyParent 자식 클래스들이다.MyChild
가 아닌 AnotherChild
일 수 있기 때문에 불가능!void addElement(Collection<? extends MyParent> c) {
c.add(new MyChild()); // 불가능(컴파일 에러)
c.add(new MyParent()); // 불가능(컴파일 에러)
c.add(new MyGrandParent()); // 불가능(컴파일 에러)
c.add(new Object()); // 불가능(컴파일 에러)
}
MyParent
타입 임을 보장하면 해결된다.void addElement(Collection<? super MyParent> c) {
c.add(new MyChild());
c.add(new MyParent());
c.add(new MyGrandParent()); // 불가능(컴파일 에러)
c.add(new Object()); // 불가능(컴파일 에러)
}
super
를 사용해 와일드카드의 최하위 타입을 정의하여 하한 경계를 설정void printCollection(Collection<? super MyParent> c) {
for( MyChild e : c ) { soutp(e); } // 컴파일 오류
for( MyParent e : c ) { soutp(e); } // 컴파일 오류
for( MyGrandParent e : c ) { soutp(e); } // 컴파일 오류
for( Object e : c ) { soutp(e); } // OK
}
Object
의 경우, Java의 모든 객체의 부모임이 명확하므로, 특별하게 가능하다.// Produce
void printCollection(Collection<? extends MyParent> c) {
for (MyParent e : c) {
System.out.println(e);
}
}
// Consume
void addElement(Collection<? super MyParent> c) {
c.add(new MyParent());
}
extends
super