PECS
Producer Extends Consumer Super
PECS 원칙
- Producer: 데이터를 생산하는 객체
- Consumer: 데이터를 소비하는 객체
원칙
- Producer
Extends
: 데이터를 읽을 때는 extends 와일드카드를 사용 <? extends T> -
Consumer
Super
: 데이터를 쓸 때는 super 와일드카드를 사용 <? super T> - <? extends T>: T 타입이나 T의 하위 타입만 허용 (읽기 전용)
- <? super T>: T 타입이나 T의 상위 타입만 허용 (쓰기 가능)
예시
// Producer (읽기)
List<? extends Number> numbers = new ArrayList<>();
Number n = numbers.get(0);
// Consumer (쓰기)
List<? super Integer> integers = new ArrayList<>();
integers.add(10);
- extends: 요소 추가 불가, 읽기만 가능
- super: 요소 읽을 때 Object 타입으로만 가능
왜 extends에서 쓰기는 불가능한가에 대해 더 살펴보겠다
List<? extends Number> numbers = new ArrayList<>();
이 경우에 numbers 리스트는 Number의 어떤 하위 타입이든 포함할 수 있따. <? extends Number>
이므로.
근데? 컴파일러 입장에선 정확히 어떤 하위 타입인지 모른다. Integer인지 Double인지 ?
타입을 모르니 numbers.add(new Integer(10))
을 허용하면
리스트가 ArrayList<Double>
일 경우 타입 안전성이 깨진다.
이런 이유로 쓰기가 불가능한 것이다.
List<? super Integer> integers = new ArrayList<>();
이 경우를 살펴보겠디.
integers 리스트는 Integer의 어떤 상위 타입이든 될 수 있다.
뭐 Number일 수도, Object일 수도 있다.
컴파일러는 정확한 타입을 모르니 가장 상위 타입인 Object로 읽을 수 있다.
근데 왜 쓰기가 가능할까? 당연한 것이다. Integer 타입이 Number든, Object든 상위 타입에 안전하게 들어갈 수 있으니 쓰기가 가능하다.