제네릭은 타입을 미리 정하지 않고 객체를 생성하는 시점에 결정할 수 있다.
package generic.test.ex3;
public class AnimalHospitalV2<T> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public void checkUp() {
// T의 타입을 메서드를 정의하는 시점에는 알 수 없다. Object의 기능만 사용
animal.toString();
animal.equals(null);
// 컴파일 오류
// System.out.println("동물 이름: " + animal.getName());
// System.out.println("동물 크기: " + animal.getSize());
// animal.sound();
}
public T bigger(T target) {
// return animal.getSize() > target.getSize() ? animal : target;
return null;
}
}
자바 컴파일러는 T에 입력되는 범위를 알 수 없다.
그렇다면 특정한 범위를 제한하려면 어떻게 해야할까?
package generic.test.ex3;
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());
animal.sound();
}
public T bigger(T target) {
return animal.getSize() > target.getSize() ? animal : target;
}
}
여기서 핵심은 T extends Animal에 있다.
타입 매개변수에 Animal과 그 자식들만 받을 수 있도록 제한했다.
이를 상한 제한(Bounded Type Parameter)이라고 한다.
즉, T는 Animal 또는 Animal의 자식 타입만 사용할 수 있다.
AnimalHospitalV3<Animal>
AnimalHospitalV3<Dog>
AnimalHospitalV3<Cat>
AnimalHospitalV3<String> hospital = new AnimalHospitalV3<>();