반응형
제네릭 와일드 카드
제네릭은 아래와 같이 오버로딩하면 컴파일 에러가 발생한다. 제네릭 타입이 다른 것만으로는 오버로딩이 성립하지 않기 때문이다.
static Juice makeJuice(FruitBox<Fruit> box) {
...
}
static Juice makeJuice(FruitBox<Apple> box) {
...
}
제네릭 타입은 컴파일러가 컴파일할 때만 사용하고 제거해버린다. 그래서 위 두 메서드는 오버로딩이 아니라 '메서드 중복 정의'이다.
이럴 때 사용하기 위해 고안된 것이 바로 '와일드 카드' 이다. 와일드 카드는 기호 '?'로 표현하는데, 와일드 카드는 어떠한 타입도 될 수 있다.
'?' 만으로는 Object 타입과 다를게 없으므로, 다음과 같이 'extends' 와 'super' 로 상한(upper bound)과 하한(lower bound)을 제한할 수 있다.
<? extends T> 와일드 카드의 상한 제한. T와 그 자손들만 가능.
<? super T> 와일드 카드의 하한 제한. T와 그 조상들만 가능.
<?> 제한 없음. 모든 타입이 가능. <? extends Object> 와 동일
* T는 Type을 의미한다. 제네릭 클래스와 달리 와일드 카드에는 <? extends T & E > 같이 '&'를 사용할 수 없다.
와일드 카드를 타입을 사용하면 아래와 같이 변경할 수 있다.
static Juice makeJuice(FruitBox<? extends Fruit> box) {
...
}
해당 메서드는 매개변수로 FruitBox에 Fruit 뿐만 아니라 Apple, Grape 등 과일의 자손들만 넣을 수 있게 된다.
만약, '? extends Object'로 하게 되면 타입을 보장받을 수 없게 된다. 즉, 과일의 자손이라는 보장이 없다.
하지만 FruitBox 클래스를 만들 때 아래와 같이 만들면 FruitBox의 요소들이 Fruit 자손이라는 것을 알고 있으므로 ? extends Object로 메서드를 만들어도 컴파일시 문제되지 않는다.
class FruitBox<T extends Fruit> extends Box<T> {
...
}
참고 자바의정석
반응형
'DEV > Java' 카테고리의 다른 글
[자바] 함수형 인터페이스(Functional Interface) (5) | 2023.02.22 |
---|---|
[자바] 람다식(Lambda expression) (1) | 2023.02.22 |
[자바] Properties (8) | 2023.02.16 |
[자바] HashMap (3) | 2023.02.15 |
[자바] HashSet (7) | 2023.02.15 |
댓글