본문 바로가기
DEV/Java

[자바] 제네릭 와일드 카드

by 어쩌다개발 2023. 2. 16.
반응형

제네릭 와일드 카드

제네릭은 아래와 같이 오버로딩하면 컴파일 에러가 발생한다. 제네릭 타입이 다른 것만으로는 오버로딩이 성립하지 않기 때문이다.

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

댓글