[자바] 지네릭 메서드

June·2021년 1월 6일
0

자바

목록 보기
31/36

메서드의 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라 한다.

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)
  1. List<T>의 요소가 Comparable인터페이스를 구현한 것이어야 한다.(<T extends Comparable>)
  2. 'T'또는 그 조상의 타입을 비교하는 Comparable이어야한다는 것(Comparable<? ssuper T>)을 의마한다. 만일 T가 Student이고, Person의 자손이라면 <? super T> 는 Student, Person, Object가 모두 가능하다.

지네릭 타입의 형변환

내용이 다소 복잡하여 다음에 필요할 때 추가할 것. 자바의 정석 687p

0개의 댓글