<? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능(주로 사용)
<? super T> : 와일드 카드의 하한 제한. T와 그 조상들만 가능
<?> : 제한 없음. 모든 타입이 가능. <? extends Object>와 동일
ArrayList<? extends Product> list = new ArrayList<Tv>(); // OK
ArrayList<? extends Product> list = new ArrayList<Audio>(); // OK
ArrayList<Product> list = new ArrayList<Tv>(); // 에러. 대입된 타입 불일치
static Juice makeJuice(FruitBox<? extends Fruit> box){
...
}
System.out.println(Juicer.makeJuice(new FruitBox<Fruit>())); // OK
System.out.println(Juicer.makeJuice(new FruitBox<Apple>())); // 와일드 카드가 있어서 OK
static <T> void sort(List<T>, list, Comparator<? super T> c)
class FruitBox<T> {
...
static<T> void sort(List<T> list, Comparator<? super T> c){
...
}
}
FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
FruitBox<Apple> appleBox = new FruitBox<Apple>();
...
System.out.println(Juicer.<Fruit>makeJuice(fruitBox)); // OK
System.out.println(Juicer.<Apple>makeJuice(appleBox)); // OK
System.out.println(Juicer.makeJuice(fruitBox)); // OK
System.out.println(Juicer.makeJuice(appleBox)); // OK
와일드 카드 : 하나의 참조변수로 서로 다른 타입이 대입된 여러 지네릭 객체를 다루기 위한 것
static Juice makeJuice(FruitBox<? extends Fruit> box){
...
}
지네릭 메서드 : 메서드를 호출할 때마다 다른 지네릭 타입을 대입할 수 있게 한 것
static <T extends Fruit> Juice makeJuice(FruitBox<T> box){
...
}
와일드 카드로 안될 때 지네릭 메서드를 사용하는 편!