- 특정 메서드에 제네릭을 적용하는 제네릭 메서드
- 앞서 살펴본 제네릭 타입과 살펴볼 제네릭 메서드는 둘 다 제네릭을 사용하기는 하지만 서로 다른 기능을 제공함
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("bound 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);
Double doubleValue = GenericMethod.<Double>numberMethod(20.0);
}
}
실행 결과
object print: 10
명시적 타입 인자 전달
generic print: 10
bound print: 10
bound print: 20.0
GenericClass<T>new GenericClass<String><T> genericMethod(T t)예) GenericMethod.<Integer>genericMethod(i)<T>와 같이 타입 매개변수를 적어줌<Integer>와 같이 타입을 정하고 호출함class Box<T> { //제네릭 타입
static <V> V staticMethod2(V t) {} //static 메서드에 제네릭 메서드 도입
<Z> Z instanceMethod2(Z z) {} //인스턴스 메서드에 제네릭 메서드 도입 가능
}
class Box<T> {
T instanceMethod(T t) {} //가능
static T staticMethod1(T t) {} //제네릭 타입의 T 사용 불가능
}
Number와 그 자식만 받을 수 있음Integer, Double, Long과 같은 숫자 타입이 Number의 자식임public static <T extends Number> T numberMethod(T t) {}
//GenericMethod.numberMethod("Hello"); // 컴파일 오류 Number의 자식만 입력 가능
<Integer>와 같이 타입 인자를 계속 전달하는 것은 매우 불편함Integer i = 10;
Integer result = GenericMethod.<Integer>genericMethod(i);
자바 컴파일러는 genericMethod()에 전달하는 인자 i의 타입이 Integer라는 것을 알 수 있음
또한 반환 타입이 Integer result라는 것도 알 수 있음
이런 정보를 통해 자바 컴파일러는 타입 인자를 추론할 수 있음
앞서 만든 MethodMain1에 다음 코드를 추가하여 실행
//타입 추론, 타입 인자 생략
System.out.println("타입 추론");
Integer result2 = GenericMethod.genericMethod(i);
Integer integerValue2 = GenericMethod.numberMethod(10);
Double doubleValue2 = GenericMethod.numberMethod(20.0);
실행 결과
//추가한 내용만 출력
타입 추론
generic print: 10
bound print: 10
bound print: 20.0
앞서 제네릭 타입으로 만들었던
AnimalHospitalV3의 주요 기능을 제네릭 메서드로 다시 만들기
package generic.ex4;
import generic.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 getBigger(T t1, T t2) {
return t1.getSize() > t2.getSize() ? t1 : t2;
}
}
checkup(), getBigger()라는 두 개의 제네릭 메서드를 정의함Animal을 상한으로 제한함package generic.ex4;
import generic.animal.Cat;
import generic.animal.Dog;
public class MethodMain2 {
public static void main(String[] args) {
Dog dog = new Dog("멍멍이", 100);
Cat cat = new Cat("냐옹이", 100);
AnimalMethod.checkup(dog);
AnimalMethod.checkup(cat);
Dog targetDog = new Dog("큰 멍멍이", 200);
Dog bigger = AnimalMethod.getBigger(dog, targetDog);
System.out.println("bigger = " + bigger);
}
}
실행 결과
동물 이름: 멍멍이
동물 크기: 100
멍멍
동물 이름: 냐옹이
동물 크기: 100
냐옹
bigger = Animal{name='큰 멍멍이', size=200}
package generic.ex4;
import generic.animal.Animal;
public class ComplexBox<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public <T> T printAndReturn(T t) {
System.out.println("animal.className: " + animal.getClass().getName());
System.out.println("t.className: " + t.getClass().getName());
// t.getName(); // 호출 불가 메서드는 <T> 타입이다. <T extends Animal> 타입이 아니
다.
return t;
}
}
package generic.ex4;
import generic.animal.Cat;
import generic.animal.Dog;
public class MethodMain3 {
public static void main(String[] args) {
Dog dog = new Dog("멍멍이", 100);
Cat cat = new Cat("냐옹이", 50);
ComplexBox<Dog> hospital = new ComplexBox<>();
hospital.set(dog);
Cat returnCat = hospital.printAndReturn(cat);
System.out.println("returnCat = " + returnCat);
}
}
실행 결과
animal.className: generic.animal.Dog
t.className: generic.animal.Cat
returnCat = Animal{name='냐옹이', size=50}
제네릭 타입 설정
class ComplexBox<T extends Animal>
제네릭 메서드 설정
<T> T printAndReturn(T t)
printAndReturn()은 제네릭 타입과는 무관하고 제네릭 메서드가 적용됨T는 상한이 없음Object로 취급됨Object로 취급되기 때문에 t.getName()과 같은 Animal에 존재하는 메서드는 호출할 수 없음public class ComplexBox<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public <Z> Z printAndReturn(Z z) {
//...
}
}