언어/Effective Java

이펙티브 자바 Item 30 - 이왕이면 제네릭 메서드로 만들라

now0204 2024. 6. 4. 16:13

 

제네릭 메서드 작성 방법

 

  • 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다.
    • Collections의 binarySearch,sort 등 알고리즘 메서드는 모두 제네릭이다.
  • 제네릭 메서드 작성법은 제네릭 타입 작성법과 비슷하다.
  • 타입 매개변수 목록은 메서드의 제한자와 반환 타입 사이에 온다. 
public static <E> Set<E> union (Set<E> s1, Set<E> s2){
    Set<E> result = new HashSet<>(s1);
    result.addAll(s2);
    return result;
}

 

위 코드의 세개의 Set집합이 타입이 모두 같아야 한다. 이를 한정적 와일드 카드 타입을 이용하면 더 유연하게 개선이 가능하다.

 


 

 

제네릭 싱글턴 팩터리 (불변 객체가 제네릭 타입)

 

불변 객체를 여라 타입으로 활용할 때가 있다. 제네릭은 런타임시 타입 정보가 소거되므로 하나의 객체를 어떤 타입으로든 매개변수화 할 수 있다.

 

객체를 매개변수화하려면 요청 타입 매개변수에 맞게 매번 그 객체의 타입을 바꿔주는 정적 팩터리가 필요하다. 

 

이 정적 팩터리 제네릭 싱글톤 팩터리라고 한다. 

List<String> str = Arrays.asList("a", "b", "c");
        str.sort(Collections.reverseOrder()); // 이처럼 함수 내부에 들어가는 객체를 함수객체라고 함

public static <T> Comparator<T> reverseOrder() {
// T 타입으로 캐스팅된 Singleton ReverseComparator 반환, 타입정보는 소거됨으로 그때그때 캐스팅만 되는 것
        return (Comparator<T>) ReverseComparator.REVERSE_ORDER; 
}

 

 

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

@SuppressWarinings("unchecked")
public static <T> UnaryOperator<T> identityFunction(){
    return (UnaryOperator<T>) IDENTITY_FN;
}

 

항등함수는 입력 값을 수정 없이 그대로 반환하는 특별한 함수이므로 T가 어떤 타입이든 UnaryOperation<T>를 사용해도 타입 안전하다.

 

2. 재귀적 한정적 타입

 

재귀적 타입 한정은 자신이 들어간 표현식을 사용하여 타입 매개변수의 허용 범위를 한정하는 개념이다.

보통 Comparable과 함께 사용된다.

 

public interface Comparable<T>{
	int compareTo(T o);
}

 

타입 매개변수 T는 Comparable<T>를 구현한 타입이 비교할 수 있는 원소의 타입을 정의한다.

 

실제 거의 모든 타입은 자기 자신과 같은 타입만 비교가 가능하다. String은 Comparable<String>을 구현 Integer는 Comparable<Integer>를 구현한다. 

public static <E extends Comparable<E>> E max(Collection<E> c);
  • 재귀적 한정적 타입을 이용해 상호 비교 할 수 있음을 표현 (E는 자신과 비교할 수 있다는 의미를 갖는다.)
public static <E extends Comparable<E>> E max(Collection<E> c){
    if(c.isEmpty()){
       throw new IllegalArgumentException("컬렉션이 비었습니다.");
    }
        
    E result = null;
    for (E e : c){
        if(result == null || e.compareTo(result) > 0){
            result = Objects.requireNonNull(e);
        }
    }
        
    return result;
}
 //추상 클래스는 아래와 같이 구현
 abstract static class Builder<T extends Builder<T>>
 public static class Builder extends PayCard.Builder<Builder>

참고자료 

https://javabom.tistory.com/40

 

[아이템 30] 이왕이면 제네릭메서드로 만들라

"이왕이면 제네릭 타입으로 만든 것 처럼 메서드도 이왕이면 제네릭 메서드로 만들자" 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다 매개변수화 타입? 제네릭 타입이 인스

javabom.tistory.com

https://velog.io/@alkwen0996/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94-%EC%95%84%EC%9D%B4%ED%85%9C30-%EC%9D%B4%EC%99%95%EC%9D%B4%EB%A9%B4-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A1%9C-%EB%A7%8C%EB%93%A4%EB%9D%BC

 

[이펙티브 자바] 아이템30 | 이왕이면 제네릭 메서드로 만들라

제네릭 메서드 작성방법 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다. 의 , 등 알고리즘 메서드는 모두 제네릭이다. 제네릭 메서드 작성법은 제네릭 타입 작성법과 비슷하

velog.io