본문 바로가기
공부/이펙티브자바

[이펙티브자바]item 31.한정적 와일드카드를 사용해 API 유연성을 높이라.

by 띵커베르 2023. 2. 15.
728x90
  • 우선 읽고 가자.
    1. 불변성(무공변성, invariant)
      • 상속 관계에 상관없이 자신의 타입만 허용하는 것을 뜻한다. Kotlin 에서는 따로 지정해주지 않으면 기본적으로 모든 Generic Class 는 무공변이다. Java 에서의 <T>와 같다.
    2. 공변성(covariant)
      • 자기 자신과 자식 객체를 허용한다. Java 에서의 와 같다. Kotlin 에서는 out 키워드를 사용해서 이를 표시한다.

    3. 반공변성(contravariant)
      • 공변성의 반대 - 자기 자신과 부모 객체만 허용한다. Java 에서의 와 같다. Kotlin 에서는 in 키워드를 사용해서 표현한다.

 

 

  • 매개변수화 타입은 불공변이다 즉 서로 다른 타입 Type1과 Type2가 있을때 List<Type1>은 List<Type2>의 하위 타입도 상위 타입도 아니다
    • ex) List<String>은 List<Object>의 하위 타입이 아니다
    • List<Object>에는 어떤 객체든 넣을 수 있지만 List<String>에는 문자열만 넣을 수 있기때문.즉 List<String>은 Lst<Object>이 하는일을 제대로 수행하지 못한다 => 리스코프 치환 원칙에 어긋난다.
  • PESC: Producer-Extends, Consumer-Super
    • 제네릭에서 매개변수 타입을 제한하는 원칙 중 하나, 제네릭에서 매개변수를 와일드카드로 지정할 때 사용됨.
    • Producer
      • 데이터를 반환하는 경우, 즉 읽기 전용일 때 제한을 두는 것  (? extends T)
      • List<? extends Number>, List<? extends E>
        • Number의 서브클래스인 Integer, Double 등을 사용할 수 있다.
        • List 에서 원소를 가져올 때는 Number나 Number의 상위 클래스 타입으로 사용할 수 있다.
        • List에 원소를 추가하려고 하면 컴파일 오류가 발생한다. List에 추가할 원소가 NUmber의 하위 클래스인지 알 수 없기 때문에
        • 어떠한 타입에(E) 하위타입의 ? 만 받겠다.
    • Consumer
      • 데이터를 소비하거나, 쓰기 전용일 때 제한을 두는 것. (? super T)
        • List<? supter Number>, List<? super E>
          • Number나 Number의 상위 클래스 타입으로 List 에 원소를 추가할 수 있다.
          • List에서 원소를 가져오려고 하면 컴파일 오류가 발생한다.
          • List에 저장된 원소가 Number의 하위 클래스인지 알 수 없기 때문.
          • 어떠한 타입에(E) 상위타입의 ? 만 받겠다.
    • 클래스 사용자가 와일드카드 타입을 신경 써야 한다면 그 API에 무슨 문제가 있을 가능성이 크다.
728x90

댓글