Java Wildcard (<? extends T>, <? super T>) 완벽 이해하기
Java Generic을 공부하다 보면 거의 반드시 막히는 구간이 바로:
<? extends T>
<? super T>
입니다.
처음 보면:
도대체 왜 이렇게 복잡하게 쓰지?
라는 생각이 들기 쉽습니다.
하지만 실제로 Wildcard는:
- Collection API
- Stream API
- Comparator
- Spring Framework
- Java 라이브러리 설계
전체와 매우 깊게 연결됩니다.
그리고 Wildcard를 이해하지 못하면:
- Generic 에러
- 타입 제한
- API 설계
- Collection 읽기/쓰기
를 제대로 이해하기 어렵습니다.
이번 글에서는:
- Wildcard란?
- extends / super 차이
- 읽기/쓰기 제한
- PECS 원칙
- Producer / Consumer
- 실무 사용 기준
까지 깊게 정리해보겠습니다.
1. Wildcard란?
Wildcard는:
“타입을 정확히 모르지만 범위를 제한하는 Generic 문법”
입니다.
대표 형태:
<?>
<? extends T>
<? super T>
2. 가장 기본 Wildcard
List<?>
의미:
“아무 타입 List 가능”
입니다.
3. 예시
List<String>
List<Integer>
List<User>
전부:
List<?>
로 받을 수 있음.
4. 그런데 왜 필요할까?
예를 들어:
void print(List<Object> list)
를 만들면:
List<String>
전달 가능할까?
5. 정답: 불가능
매우 중요.
List<String>
≠
List<Object>
입니다.
6. 왜 그럴까?
만약 허용되면:
list.add(100);
가능해져서:
String List에 Integer 저장 가능
문제 발생.
7. 그래서 등장한 것이 Wildcard
void print(List<?> list)
이렇게 하면:
모든 타입 List 허용
가능.
8. 하지만 제약 존재
List<?> list
에서는:
list.add(...)
거의 불가능.
9. 왜 add가 안 될까?
현재 JVM 입장에서는:
“무슨 타입인지 모름”
입니다.
즉:
안전하게 넣을 수 없음
10. 대신 읽기는 가능
Object obj = list.get(0);
가능.
왜냐하면:
어떤 객체든 Object
이기 때문.
11. extends 등장
대표 문법:
<? extends Number>
12. 의미
Number 또는 그 하위 타입
입니다.
즉:
Integer
Double
Long
등 허용.
13. 사용 예시
void print(List<? extends Number> list)
14. 가능한 타입
List<Integer>
List<Double>
List<Long>
전부 가능.
15. 왜 유용할까?
공통 부모 타입 기반 처리 가능.
예:
for (Number n : list)
가능.
16. extends 핵심 특징
매우 중요.
읽기(Read) 안전
쓰기(Write) 제한
입니다.
17. 왜 쓰기 제한될까?
예:
List<? extends Number>
실제 타입이:
List<Integer>
일 수도 있음.
그런데:
list.add(Double.valueOf(1.2));
허용되면 위험.
18. 그래서 add 불가능
list.add(...)
거의 금지.
(단 null은 가능)
19. super 등장
대표 문법:
<? super Integer>
20. 의미
Integer 또는 그 부모 타입
입니다.
즉:
List<Integer>
List<Number>
List<Object>
허용.
21. super 핵심 특징
매우 중요.
쓰기(Write) 안전
읽기(Read) 제한
입니다.
22. 왜 쓰기 안전할까?
예:
List<? super Integer>
이면 최소한:
Integer 저장 가능
보장.
23. 읽기는 왜 제한될까?
실제 타입이:
List<Object>
일 수도 있기 때문.
즉:
Integer i = list.get(0);
안전 보장 불가.
24. 그래서 읽을 땐 Object
Object obj = list.get(0);
만 안전.
25. extends vs super 핵심 비교
| 문법 | 의미 | 읽기 | 쓰기 |
| <? extends T> | T 하위 타입 | 안전 | 제한 |
| <? super T> | T 부모 타입 | 제한 | 안전 |
26. 이것이 바로 PECS
매우 중요합니다.
Java Generic 핵심 원칙.
27. PECS란?
Producer Extends
Consumer Super
28. 의미
| 역할 | 사용 |
| 데이터를 생산(읽기) | extends |
| 데이터를 소비(쓰기) | super |
29. Producer 예시
List<? extends Number>
는:
데이터 읽기용
에 적합.
30. Consumer 예시
List<? super Integer>
는:
데이터 저장용
에 적합.
31. 실무 예시 1
public static <T>
void copy(
List<? super T> dest,
List<? extends T> src
)
32. 왜 이렇게 설계할까?
src는:
데이터 제공(Producer)
↓
extends
dest는:
데이터 저장(Consumer)
↓
super
33. Stream API에서도 매우 많이 사용
예:
Comparator<? super T>
34. 왜 super 사용할까?
Comparator는:
비교 대상 소비
하기 때문.
35. Collection.addAll()
실제 Java 내부도 비슷.
addAll(Collection<? extends E>)
36. 이유
추가 대상 Collection은:
데이터 생산자
이기 때문.
37. Wildcard 없으면 문제
API 유연성 매우 감소.
즉:
상속 구조 활용 어려움
38. Generic과 상속 혼동 주의
매우 중요.
Integer extends Number
지만:
List<Integer>
≠
List<Number>
입니다.
39. 왜 위험할까?
만약 허용되면:
List<Integer> ints = ...
List<Number> nums = ints;
nums.add(Double.valueOf(1.5));
가능해짐.
즉:
Integer List 깨짐
40. Wildcard 없는 Generic 메서드와 차이
예:
<T>
는:
구체 타입 추론
목적.
Wildcard는:
범위 제한
목적.
41. 실무에서 자주 하는 실수
1) extends인데 add 하려 함
컴파일 오류 발생.
2) super인데 읽기 타입 확정하려 함
Object만 안전.
3) PECS 이해 부족
API 설계 어려움.
4) Generic 상속 착각
List<Integer>
≠
List<Number>
매우 중요.
42. 핵심 흐름 요약
extends
= 읽기 중심
super
= 쓰기 중심
43. 가장 중요한 핵심 한 줄
PECS:
읽기(Producer)는 extends,
쓰기(Consumer)는 super
입니다.
44. 정리
Wildcard는 단순 Generic 문법이 아닙니다.
실제로는:
- Collection API
- Stream API
- Comparator
- Java 라이브러리 설계
- 타입 안정성
전체와 연결되는 매우 중요한 Generic 핵심 개념입니다.
특히 실무에서는:
- PECS 원칙
- extends/super 차이
- 읽기/쓰기 제한
- Generic 상속 관계
- Collection API 설계
를 정확히 이해하는 것이 매우 중요합니다.
다음 글에서는:
Immutable Collection 만들기
를 unmodifiableList, List.of(), defensive copy, 불변 객체 설계까지 포함해서 깊게 정리해보겠습니다.
'language > java' 카테고리의 다른 글
| Java ConcurrentHashMap 기초 완벽 이해하기 (0) | 2026.05.27 |
|---|---|
| Java Immutable Collection 만들기 완벽 이해하기 (0) | 2026.05.27 |
| Java Generic(제네릭) 기초 완벽 이해하기 (0) | 2026.05.27 |
| Java Iterator와 Iterable 완벽 이해하기 (0) | 2026.05.27 |
| Java Comparable vs Comparator 완벽 이해하기 (0) | 2026.05.27 |
댓글