본문 바로가기

1_스터디

[Effectvie Java] ITEM 31. 한정적 와일드카드를 사용해 API 유연성을 높이라.

반응형

매개변수화 타입은 불공변(invariant)이다.

리스코프 치환원칙에 어긋난다.

상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 문제가 없어야 한다. 즉, B가 A의 자식일 때, A 타입을 사용하는 부분에서 B로 치환해도 문제없이 동작이 되어야 한다.

https://brownbears.tistory.com/579

 

[SOLID] 리스코프 원칙 법칙이란 (Liskov Substitution Principle, LSP)

리스코프 치환 법칙은 SOLID 원칙에서 L에 해당하는 법칙입니다. 해당 법칙은 상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 문제가 없어야 합니다. 즉, B가 A의 자식일 때, A 타입을 사

brownbears.tistory.com

한정적 와일드카드 타입

Iterable<? extends E> / E의 하위 타입의 Iterable

 

E 생산자(producer) 매개변수에 와일드카드 타입 적용

public void pushAll(Iterable<? extends E> src) {
    for( E e : src )
        push(e);
}

E 소비자(Consumer) 매개변수에 와일드카드 타입 적용

public void popAll(Collection<? super E> dst) {
    while( !isEmpty() )
        dst.add( pop() );
}

 

유연성을 극대화하려면 원소의 생산자나 소비자용 입력 매개변수에 와일드카드 타입을 사용하라.
 
매개변수가 생잔자와 소비자 역할을 동시에 한다면 와일드카드 타입을 써도 좋을 게 없다.
PECS : producer-extends, consumer-super

 

수정한 선언을 사용하면, 다음 코드도 말끔히 컴파일된다.

Set<Integer> integers = Set.of(1, 3, 5);
Set<Double> doubles = Set.of(2.0, 4.0, 6.0);
Set<Number> numbers = union(integers, doubles);

(자바 8부터 제대로 컴파일 가능)

자바 7까지는 반환 타입을 명시해야한다.

Set<Number> numbers = union(integers, doubles); // imcompatible types 오류 발생

목표 타이핑(target typing)은 자바 8부터 지원

// 자바 7 이하에서도 깨끗이 컴파일 된다.
Set<Number> numbers = Union.<Number>union(integers, doubles);

 

핵심정리

  • 조금 복잡하더라도 와일드카드 타입을 적용하면 API가 훨씬 유연해진다.
  • 널리 쓰일 라이브러리를 작성한다면 반드시 와일드카드 타입을 적절히 사용하자.
  • PECS : producer-extends, consumer-super
  • Comparable과 Comparator는 모두 소비자라는 사실을 잊지 말자.
반응형