30. 이왕이면 제네릭 메소드로 만들라

신명철·2022년 2월 23일
0

Effective Java

목록 보기
28/80

제네릭 메소드

클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메소드보다 제네릭 메소드가 더 안전하고 사용하기도 쉽다. 타입과 마찬가지로, 메소드도 형변환 없이 사용할 수 있는 편이 좋으며 많은 경우 그렇게 하려면 제네릭 메소드가 되어야 한다.

매개변수화 타입을 받는 정적 유틸리티 메소드는 보통 제네릭이다. 다음 문제가 있는 메소드를 보자.

public static Set union(Set s1, Set s2) {
	Set result = new HashSet(s1);
	result.addAll(s2);
	retun result;
}
  • 위 메소드는 타입 안전하지 않은 메소드이기 때문에 타입 안전하게 만들어야 한다.
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
	Set result = new HashSet(s1);
	result.addAll(s2);
	retun result;
}

제네릭 싱글톤 팩터리 패턴

불변 객체를 여러 타입으로 활용할 수 있게 만들 필요가 있을 때가 있다. 제네릭은 런타임에 타입 소거 되기 때문에 하나의 객체를 어떤 타입으로든 매개변수화 할 수 있다. 하지만 이렇게 하려면 요청한 타입 매개변수에 맞게 매번 그 객체의 타입을 바꿔주는 정적 팩터리를 만들어야 한다. 이를 제네릭 싱글톤 팩터리 패턴이라 한다. 다음 항등함수(identityFunction())에 대한 코드를 보자.

private static UnaryOperator<Object> IDENTIFY_FN = (t) -> t;

@SuppressWarnings("unchecked")
public static<T> UnaryOperator<T> identityFunction() {
    return  (UnaryOperator<T>) IDENTIFY_FN;
}
Number[] numbers = {1, 2.0, 3L};
UnaryOperator<Number> sameNumber = identityFunction();
for(Number number : numbers){
	systeam.out.println(sameNumber.apply(number));
}
  • 타입별로 하나씩 만들어야 했을 항등함수 객체를 제네릭 싱글톤 패턴을 통해 하나의 객체로 만족시켰다.
  • 이 코드는 비검사 형변환 경고가 발생하지만 항등함수는 언제나 같은 값을 반환하는 특별한 함수이므로 (unaryOperator<T>)를 사용해도 타입 안전하다. 그러니 @SupressWarning으로 경고를 숨겨도 안심할 수 있다.

재귀적 타입 한정

자기 자신이 들어간 표현식을 사용해 타입 매개변수의 허용 범위를 한정하는 것을 재귀적 타입 한정이라고 한다. 이는 주로 타입의 자연적 순서를 정하는 Comparable 인터페스와 함께 쓰인다. Comparable<T> 을 통해 자기 자신과 같은 타입의 원소와 비교가 가능하다.

public static <E extends Comparable<E>> E max(Collection<E> c) {
    if (c.isEmpty())
        throw new IllegalArgumentException("Empty Collection");

    E result = null;
    for (E e : c)
        if (result == null || e.compareTo(result) > 0)
            result = Objects.requireNonNull(e);

    return result;
}
  • 타입 한정인 <E extends Comparable<E>>는 모든 타입 E 는 자신과 비교할 수 있다 라고 읽을 수 있다. 라고 읽을 수 있다.
profile
내 머릿속 지우개

0개의 댓글