관리 메뉴

루시와 프로그래밍 이야기

ITEM30. 이왕이면 제네릭 메서드로 만들라 본문

스터디/이펙티브 자바

ITEM30. 이왕이면 제네릭 메서드로 만들라

Lucy_Ko 2022. 10. 13. 00:54

메서드도 제네릭으로 만들 수 있다.

매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제너릭이다.

Collections의 알고리즘 메서드 (binarySearch, sort 등)는 모두 제너릭이다.


로타입 사용 X (ITEM26)

※로타입이란? 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않았을 때

  • Set<T> 를 제네릭타입
  • Set로만 선언하여 사용했을 경우 로타입
class Example {
    public static Set union(Set s1, Set s2) {
        Set result = new HashSet(s1);
        result.addAll(s2);
        return result;
    }
}
Unchecked call to 'HashSet(Collection<? extends E>)' as a member of raw type 'java.util.HashSet'
Unchecked call to 'addAll(Collection<? extends E>)' as a member of raw type 'java.util.Set'

 

 

※제네릭 메소드는 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드이다.
ex)public <타입 파라미터 . . . > 리턴타입 메소드명 (매개변수, . . . ) { . . . }
타입 파라미터 : https://blog.naver.com/PostView.nhn?blogId=zzang9ha&logNo=222059024135

class Example {
    public static <E> Set<E> union(Set<E> si, Set<E> s2) {
        Set<E> result = new HashSet<>(sl);
        result.addAll(s2);
        return result;
    }
}
  • 이 메서드는 경고 없이 컴파일 되며, 타입 안전하고, 쓰기도 쉽다.
  • 이 메서드를 사용하는 간단한 프로그램
  • 직접 형변환하지 않아도 어떤 오류나 경고 없이 컴파일된다.
class Example {
    public static void main(String[] args) {
        Set<String> guys = Set.of("톰", "딕", "해리");
        Set<String> stooges = Set.of("래리", "모에닉", "컬리");
        Set<String> aflCio = union(guys, stooges);
        System.out.println(aflCio);
    }
}
//"[모에, 톰, 해리, 래리, 컬리, 딕]"이 출력 된다.
  • union 메서드는 집합 3개 (입력 2개, 반환 1개)의 타입이 모두 같아야 한다.
    이를 한정적 와일드카드 타입(ITEM31)을 사용하여 더 유연하게 개선할 수 있다.
  • 불변 객체를 여러 타입으로 활용할 수 있게 만들어야 할 때가 있다.
    제네릭은 런타임에 타입 정보가 소거(ITEM28)되므로 하나의 객체를 어떤 타입으로든 매개변수화 할 수 있다.
  • 하지만 이렇게 하려면 요청한 타입 매개 변수에 맞게 매번 그 객체의 타입을 바꿔주는 정적 팩터리를 만들어야 한다.
    이 패턴을 제네릭 싱글턴 팩터리라 한다.

정리

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

 

 

 

 

 

 

 

 

 

Comments