public class GenericBox<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
public class BoxMain3 {
public static void main(String[] args) {
GenericBox<Integer> integerBox = new GenericBox<>(); // 생성 시점에 T의 타입이 결정
integerBox.set(10); // Integer 타입만 허용, 그외 컴파일 오류
Integer integer = integerBox.get(); // Integer 타입 반환 (캐스팅 X)
System.out.println("integer = " + integer);
GenericBox<String> stringBox = new GenericBox<>();
stringBox.set("Hello");
String string = stringBox.get();
System.out.println("string = " + string);
// 그 외 원하는 모든 타입 사용 가능
}
}
GenericBox integerBox = new GenericBox();
GenericBox<Object> integerBox = new GenericBox<>();
package generic;
import generic.animal.Animal;
public class AnimalHospitalV3 <T extends Animal>{
private T animal;
public void set(T animal){
this.animal = animal;
}
public void checkup(){
System.out.println("동물 이름 : " + animal.getName());
System.out.println("동물 크기 : " + animal.getSize());
}
public T getBigger(T target){
return animal.getSize() > target.getSize() ? animal : target;
}
}
package generic.ex4;
public class GenericMethod {
public static Object objMethod(Object obj){
System.out.println("Object print : " + obj);
return obj;
}
public static <T> T genericMethod(T t){
System.out.println("Generic print : " + t);
return t;
}
public static <T extends Number> T numberMethod(T t){
System.out.println("Object print : " + t);
return t;
}
}
package generic.ex4;
public class MethodMain1 {
public static void main(String[] args) {
Integer i = 10;
Object object = GenericMethod.objMethod(i);
// 타입인자 (Type Argument) 명시적 전달
System.out.println("명시적 타입 인자 전달");
Integer result = GenericMethod.<Integer>genericMethod(i);
Integer integerValue = GenericMethod.<Integer>numberMethod(10);
GenericMethod.<Double>numberMethod(20.0);
// 타입 추론, 생략 가능
Integer result1 = GenericMethod.genericMethod(15);
Integer integerValue1 = GenericMethod.numberMethod(20);
}
}
package generic.ex5;
import generic.animal.Animal;
public class WildcardEx {
static <T> void printGenericV1(Box<T> box){
System.out.println("T = " + box.get());
}
static void printWildcardV1(Box<?> box){
System.out.println("? = " + box.get());
}
static <T extends Animal> void printGeneticV2(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 printAndReturnGenetic(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;
}
}
제네릭 메서드와 와일드 카드를 비교할 수 있게 같은 기능을 각각 하나씩 배치해두었다.
와일드 카드는 ?를 사용해서 정의한다.
와일드 카드에서도 마찬가지로 상한 제한을 둘 수 있다.
'? extends Animal'을 지정했다. 이렇게 하면 Animal과 그 하위 타입만 입력 받는다. 만약 다른 타입을 입력하면 컴파일 오류가 발생한다.
결과적으로 Animal 타입의 기능을 호출할 수 있다.
// Animal 포함 상위 타입 전달 가능
static void writeBox(Box<? super Animal> box) {
box.set(new Dog("멍멍이", 100);
}