[Java] 7. 제네릭-와일드카드(Wildcard) 타입
제네릭에 와이드카드를 코드에 따른 주석으로 설명한 포스팅이다.
1. 제네릭 와일드카드(wildcard)
자바의 제네릭에서 알 수 없는 타입을 제한하고 싶을 때 와일드카드 문자인 ?를 사용한다.
<? extends T>
: 와일드 카드의 상한 제한. T와 그 자손들만 가능
<? super T>
: 와일드 카드의 하한 제한. T와 그 조상들만 가능
<?>
: 제한 없음. 모든 타입의 가능. <? extends Object>와 동일 åå
2. 와일드카드 예제
포스팅 설명 대신 예제 코드와 주석으로 대신한다.
Fruit.java
//음식
class Food {
}
//과일
class Fruit<T> extends Food {
}
//사과
class Apple extends Fruit {
}
//바나나
class Banana extends Fruit {
}
class FruitBox<T extends Fruit> {
private T fruitName;
ArrayList<T> list = new ArrayList<T>();
void add(T fruit) {
this.add(fruit);
}
T get(int i) {
return list.get(i);
}
int size() {
return list.size();
}
}
class Cart<T> {
}
ExGenericTypeExtends.java
public class ExGenericTypeExtends {
public static void main(String... args) {
//FruitBox 는 과일 클래스를 상속 받는 과일만 생성자로 만들 수 있다.
//T는 자손 타입을 미리 정의해놓고 사용하는 방법
//EX CASE 1
FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
fruitBox = new FruitBox<Fruit>();
//과일로 과일박스를 만들면
//부모인 fruit 으로는 자식인 과일 종류(Apple, Banana)들을 담을 수가 있다.
fruitBox.add(new Apple());
fruitBox.add(new Banana());
//EX CASE 2
//사과로 사과박스를 만들면 사과(Apple)만 담을 수 있다.
FruitBox<Apple> appleBox = new FruitBox<Apple>();
appleBox.add(new Apple());
//appleBox.add(new Banana());//에러 발생, 사과박스에 바나나를 담으려고 해서 에러
//EX CASE 3 : 와일드카드
//3-1. <? extends T> : 와일드 카드의 상한 제한. T와 자손들만 가능
//와일드 카드로 <? extends Fruit> 다형성으로 과일 자식(Apple, Banana)들 객체 모두 대입이 가능하다.
FruitBox<? extends Fruit> fruitWildBox = new FruitBox<Fruit>();
fruitWildBox = new FruitBox<Fruit>();
fruitWildBox = new FruitBox<Apple>();
fruitWildBox = new FruitBox<Banana>();
//3-2. <? super T> : 와일드 카드의 하한 제한. T와 조상들만 가능
Cart<? super Fruit> foodSuperCart = new Cart<Fruit>();
foodSuperCart = new Cart<Food>();
foodSuperCart = new Cart<Fruit>();
//foodSuperCart = new Cart<Apple>();//에러 발생, 자손은 불가
//EX CASE 4 : 메서드의 매개변수에 와이드 카드 예제
//4-1. 와일드 카드 없는 경우 : FruitBox<Fruit> fruit
//지정 된 타입만 대입이 가능
FruitCart.addOnlyFruitCart(new FruitBox<Fruit>());
//FruitCart.addOnlyFruitCart(new FruitBox<Apple>());//에러 발생
//4-2. <? extends T> : FruitBox<? extends Fruit> fruit
//와일드 카드의 상한 제한. T와 자손들만 가능
FruitCart.addWildCart1(new FruitBox<Fruit>());
FruitCart.addWildCart1(new FruitBox<Apple>());
FruitCart.addWildCart2(new FruitBox<Fruit>());
FruitCart.addWildCart2(new FruitBox<Banana>());
//4-3. <? super T> : Cart<? super Fruit> fruit
//와일드 카드의 하한 제한. T와 조상들만 가능
FruitCart.addSuperCart(new Cart<Food>());
FruitCart.addSuperCart(new Cart<Fruit>());
//FruitCart.addSuperCart(new Cart<Apple>());//에러, 자손 불가
}
static class FruitCart {
//과일박스의 Fruit 만 들어 올 수 있음
//- new FruitBox<Fruit>()
static void addOnlyFruitCart(FruitBox<Fruit> fruit) {
}
//와이드카드로 과일박스 자기와 자손들도 가능 Fruit, Apple, Banana
//- new FruitBox<Fruit>()
//- new FruitBox<Apple>()
static <T extends Fruit> void addWildCart1(FruitBox<T> fruit) {
}
//addWildCart1 와 addWildCart2 메서드는 동일함
static void addWildCart2(FruitBox<? extends Fruit> fruit) {
}
//와일드카드 super 로 자기와 조상들만 가능 Fruit, Food
static void addSuperCart(Cart<? super Fruit> fruit) {
}
}
}
헤당 포스팅도 끝