메서드의 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라 한다.
static <T> void sort(List<T> list, Comparator<? super T> c)
지네릭 클래스의 정의된 타입 매개변수와 지네릭 메서드의 정의된 타입 매개변수는 전혀 별개의 것이다. 같은 타입 문자 T를 사용해도 같은 것이 아니라는 것에 주의해야 한다.
class FruitBox<T> {
...
static <T> void sort(List<T> list, Comparator<? super T> c) {
...
}
}
위의 코드에서 지네릭 클래스 FruitBox에 선언된 타입 매개변수 T와 지네릭 메서드 sort()에 선언된 타입 매개변수 T는 타입 문자만 같을 뿐 서로 다른 것이다. 그리고 sort()가 static메서드라는 것에 주목하자. static멤버에는 타입 매개변수를 사용할 수 없지만, 이처럼 메서드에 지네릭 타입을 선언하고 사용하는 것은 가능하다.
메서드에 선언된 지네릭 타입은 지역 변수를 선언한 것과 같다고 생각하면 이해하기 쉬운데, 이 타입 매개변수는 메서드 내에서만 지역적으로 사용될 것이므로 메서드가 static이건 아니건 상관이 없다.
앞서 나왔던 makeJuice()를 지네릭 메서드로 바꾸면 다음과 같다.
static Juice makeJuice(FruitBox<? extends Fruit> box) {
String tmp = "";;
for (Fruit f : box.getList()) {
tmp += f + " ";
}
return new Juice(tmp);
}
static <T extends Fruit> Juice makeJuice<FruitBox<T> box) {
String tmp = "";
for (Fruit f : box.getList()) {
tmp += f + " ";
}
return new Juice(tmp);
}
이제 이 메서드를 호출할 때는 아래와 같이 타입 변수에 타입을 대입해야 한다.
FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
FruitBox<Apple> appleBox = new FruitBox<Apple>();
...
System.out.println(Juicer.<Fruit>makeJuice(fruitBox));
System.out.println(Juicer.<Apple>makeJuice(appleBox));
지네릭 메서드는 매개변수의 타입이 복잡할 때도 유용하다. 만일 아래와 같은 코드가 있다면 타입을 별도로 선언함으로써 코드를 간략히 할 수 있다.
publci static void printAll(ArrayList<? extends Product> list, ArrayList<? extends Product> list2) {
...
}
public static <T extends Product> void printAll(ArrayList<T> list, ArrayList<T> list2) {
...
}
어려운 예제
public static <T extends Comparable<? super T>> void sort(List<T> list)
List<T>
의 요소가 Comparable인터페이스를 구현한 것이어야 한다.(<T extends Comparable>
)<? super T>
는 Student, Person, Object가 모두 가능하다. 내용이 다소 복잡하여 다음에 필요할 때 추가할 것. 자바의 정석 687p