자바에서는 제네릭을 좀 더 간편하게 이용할 수 있도록 와일드카드를 지원하고 있다.
참고로 와일드카드는 프로그래밍에서 ?, * 과 같은 하나 이상의 특수문자를 말한다.
와일드카드는 "구체적인 타입은 모르지만 어떤 타입인지는 상관없다"는 의미로 사용된다.
package generic.test.ex5;
import generic.animal.Animal;
import generic.animal.Cat;
import generic.animal.Dog;
public class WhildcardMain1 {
public static void main(String[] args) {
Box<Object> objectBox = new Box<>();
Box<Dog> dogBox = new Box<>();
Box<Cat> catBox = new Box<>();
dogBox.set(new Dog("멍멍이", 100));
WildcardEx.printGenericV1(dogBox);
WildcardEx.printWildcardV1(dogBox);
WildcardEx.printGenericV2(dogBox);
WildcardEx.printWildCardV2(dogBox);
Dog dog = WildcardEx.printAndReturnGeneric(dogBox);
Animal animal = WildcardEx.printAndReturnWildcard(dogBox);
}
}
package generic.test.ex5;
import generic.animal.Animal;
public class WildcardEx {
static <T> void printGenericV1(Box<T> box) {
System.out.println("T = " + box.get());
}
// Box<Dog>, Box<Cat>, Box<Object>
static void printWildcardV1(Box<?> box) {
System.out.println("? = " + box.get());
}
static <T extends Animal> void printGenericV2(Box<T> box) {
T t = box.get();
System.out.println("이름 = " + t.getName());
}
static void printWildCardV2(Box<? extends Animal> box) {
Animal animal = box.get();
System.out.println("이름 = " + animal.getName());
}
static <T extends Animal> T printAndReturnGeneric(Box<T> box) {
T t = box.get();
System.out.println("이름: " + t.getName());
return t;
}
static Animal printAndReturnWildcard(Box<? extends Animal> box) {
Animal animal = box.get();
System.out.println("이름 = " + animal.getName());
return animal;
}
}
제네릭 메서드는 타입 매개변수를 선언하고, 메서드 호출 시 타입이 결정된다.
반면 와일드카드는 새로운 타입 매개변수를 선언하지 않는다.
이미 존재하는 제네릭 타입을 조금 더 유연하게 받을 수 있도록 도와준다.
단순히 제네릭 타입을 받아서 사용만 한다면 와일드카드가 더 간결하다.
하지만 입력받은 타입을 그대로 반환하거나, 여러 매개변수의 타입 관계를 유지해야 한다면 제네릭 메서드를 사용해야 한다.
따라서 와일드카드와 제네릭 메서드 중 어느 것이 더 좋은 것이 아니라, 상황에 맞게 선택하는 것이 중요하다.