들어가며
제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메소드보다 제네릭 메소드가 더 안전하며 사용하기도 쉽다. 타입과 마찬가지로, 메소드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메소드가 되어야 한다. 역시 타입과 마찬가지로 형변환을 해줘야 하는 기존 메소드는 제네릭하게 만들자.
매개변수화 타입을 받는 정적 유틸리티 메소드는 보통 제네릭이다. 다음은 두 집합의 합집합을 반환하는 문제가 있는 메소드이다.
1 | public static Set union(Set s1, Set s2) { |
위 메소드는 타입 안전하지 않은 메소드이기 때문에 이를 타입 안전하게 만들어야 한다.
1 | public static <E> Set<E> union(Set<E> s1, Set<E> s2) { |
제네릭 싱글톤 팩터리 패턴
때로는 불변 객체를 여러 타입으로 활용할 수 있게 만들어야 할 때가 있다. 제네릭은 런타임에 타입 정보가 소거되므로 하나의 객체를 어떤 타입으로든 매개변수화할 수 있다. 하지만 이렇게 하려면 요청한 타입 매개변수에 맞게 매번 그 객체의 타입을 바꿔주는 정적 팩터리를 만들어야 한다. 이를 제네릭 싱글톤 팩터리 패턴이라 한다. 다음 항등함수(identity function)에 대한 코드를 보자.
1 | private static UnaryOperator<Object> IDENTIFY_FN = (t) -> t; |
항등함수객체는 무상태이니 요청마다 매번 새로 만드는 것은 낭비다. 그리고 타입별로 하나씩 만들어야 했겠지만 소거 방식을 사용한 덕에 제네릭 싱글턴 하나면 충분하다. 이 코드는 비검사 형변환 경고가 발생하지만 항등함수는 언제나 같은 값을 반환하는 특별한 함수이므로 (unaryOperator\@SuppressWarnings
로 경고를 숨겨도 안심할 수 있다.
재귀적 타입 한정
재귀적 타입 한정은 자기 자신이 들어간 표현식을 사용하여 타입 매개변수의 허용 범위를 한정하는 것이다. 이는 주로 타입의 자연적 순서를 정하는 Comparable 인터페이스와 함께 쓰인다. 여기서 Comparable\
1 | public static <E extends Comparable<E>> E max(Collection<E> c); |
위 코드는 타입 한정을 사용하여 자신의 타입과 상호 비교가 가능하다는 뜻을 표현하고 있다. 이를 구현한 코드는 다음과 같다.
1 | public static <E extends Comparable<E>> E max(Collection<E> c) { |