자바기초
제네릭의 필요성(제네릭 메서드 편)
lby132
2025. 6. 15. 09:33
제네릭 메서드 선언
package genericBox.test.ex4;
import genericBox.animal.Animal;
public class AnimalMethod {
public static <T extends Animal> void checkup(T t) {
System.out.println("동물 이름: " + t.getName());
System.out.println("동물 크기: " + t.getSize());
t.sound();
}
public static <T extends Animal> T bigger(T t1, T t2) {
return t1.getSize() > t2.getSize() ? t1 : t2;
}
}
제네릭 메서드 사용
package genericBox.test.ex4;
import genericBox.animal.Cat;
import genericBox.animal.Dog;
public class MethodMain2 {
public static void main(String[] args) {
Dog dog = new Dog("멍멍이", 100);
Cat cat = new Cat("냐옹이", 300);
// AnimalMethod 뒤에 오는 <Dog>, <Cat> 는 컴파일러가 인자값으로 추론이 가능 하므로 제거 해도 됨
AnimalMethod.checkup(dog);
AnimalMethod.checkup(cat);
Dog targetDog = new Dog("큰 멍멍이", 200);
Dog bigger = AnimalMethod.bigger(dog, targetDog);
System.out.println("bigger = " + bigger);
}
}
두번째는 제네릭 클래스와 제네릭 메서드 두 곳에서 사용
제네릭 선언
package genericBox.test.ex4;
import genericBox.animal.Animal;
public class ComplexBox<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public <Z> Z printAndReturn(Z z) {
System.out.println("animal.className: " + animal.getClass().getName());
System.out.println("t.className: " + z.getClass().getName());
return z;
}
}
선언된 제네릭 사용
package genericBox.test.ex4;
import genericBox.animal.Animal;
import genericBox.animal.Cat;
import genericBox.animal.Dog;
public class MethodMain3 {
public static void main(String[] args) {
Dog dog = new Dog("멍멍이", 100);
Cat cat = new Cat("냐옹이", 300);
ComplexBox<Dog> hospital = new ComplexBox<>();
hospital.set(dog);
Cat returnCat = hospital.printAndReturn(cat);
System.out.println("returnCat = " + returnCat);
}
}
만약 제네릭 타입이 클래스와 메서드 모두 같을땐?
package genericBox.test.ex4;
import genericBox.animal.Animal;
public class ComplexBox<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public <T> T printAndReturn(T z) {
System.out.println("animal.className: " + animal.getClass().getName());
System.out.println("t.className: " + z.getClass().getName());
return z;
}
}
기본적으로 제네릭 타입(클래스) 보다 제네릭 메서드가 높은 우선순위를 가진다.
따라서 printAndReturn()은 제네릭 타입과는 무관하고 제네릭 메서드가 적용된다. 여기서 제네릭 타입과 제네릭 메서드가 같은 T 를 받지만 사실상 제네릭 메서드와 제네릭 타입과는 무관하다 다른 T 라고 생각하면 된다. 제네릭 타입과 메서드 각자 넣어준 타입으로 들어온다.
그래도 프로그래밍에서는 모호한 것은 좋지 않기 때문에 좀더 위쪽 코드 같이 T로 하기보다는 메서드는 Z 로 하는 식으로 다르게 가는게 좋다.