자바기초

제네릭의 필요성(제네릭 메서드 편)

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 로 하는 식으로 다르게 가는게 좋다.