티스토리 뷰
스프링 부트를 공부하면서, ResponseEntity 와 같은 클래스들은 내부가 어떻게 생겼는지 궁금하여 클래스를 뜯어보는 일이 자주 있게 되었고, 그때 마다 만났던 문법인 자바의 제네릭 와일드 카드라는 문법에 대해서 정리해보려고 한다.
자바의 와일드 카드 문법에 대해서 알아보기전에, 공변, 불공변 개념에 대해서 알고 가야한다.
● 공변 : S 가 T 의 하위 타입이면,
- S[] 는 T[] 의 하위 타입이다.
- List<S> 는 List<T> 의 하위 타입이다.
● 반공변 (공변의 반대) : S 가 T의 하위 타입이면,
- T[] 는 S[] 의 하위 타입이다.
- List<T> 는 List<S> 의 하위 타입이다.
● 무공변 / 불공변 : S 와 T 는 서로 관계가 없다.
List<S> 와 List<T> 는 서로 다른 타입이다
느낌상 업캐스팅, 다운캐스팅과 비슷한 맥락인 것같은데, 맞다.
예시를 통해서 이해해보자.
배열은 공변이다. 이 코드에서는, Integer는 Object의 하위 타입이므로, Integer[]도 역시 Object[]의 하위 타입이다 ( 공변 ).
따라서 컴파일 에러없이 잘 실행된다.
@Test
void genericTest() {
Integer[] integers = new Integer[]{1, 2, 3};
printArray(integers);
}
void printArray(Object[] arr) {
for (Object e : arr) {
System.out.println(e);
}
}
하지만, 제네릭은 불공변이다. 그렇기 때문에, Integer는 Object의 하위 타입인데도 불구하고, List<Integer>는 List<Object>의 하위 타입이 아니다. ( 둘은 아무 관계가 없다. )
따라서 아래 코드는 컴파일 에러가 난다.
@Test
void genericTest() {
List<Integer> list = Arrays.asList(1, 2, 3);
printCollection(list); // 컴파일 에러 발생
}
void printCollection(Collection<Object> c) {
for (Object e : c) {
System.out.println(e);
}
}
즉, 제네릭은 하나의 특정 타입으로만 특정해서 사용할 수 있는 것이다 ( 불공변이니까, "여러가지에 써야지!" 라고 생각해서 클래스를 만들때 <Object>라고 썼지만, 말그대로 Object타입만 받아올 수 있는 것이다. )
이러한 제네릭의 문제를 해결하기 위해서 나온 문법이 바로 와일드 카드이다.
★ 와일드 카드 ( "?" )
다음은 와일드 카드 문법을 이용한 예제이다. 말그대로, 아무 타입이나 와도 된다.
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
하지만, 요소를 추가(add)하지는 못한다. 아무 타입이나 받아들아들이는 와일드 카드("?")의 타입은 unknown type이므로, 컴파일러가 구체적으로 어떤 타입인지 알 수 없다. 이 컬렉션에 요소를 추가하는 것을 허용하면 Integer, String 등 다양한 클래스를 추가할 수 있게 되어 타입 안전성을 보장할 수 없으므로, 요소를 추가하는 연산을 허용하지 않는다.
void genericTest() {
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 컴파일 에러
}
반면, get으로 값을 꺼내는 작업은 상관없다. get으로 값을 꺼낸 후에는 적절하게 타입 안정성 처리를 해줄 수 있기 때문이다.
여기까지가 자바 와일드 카드 문법의 기본이다.
다음 자바 와일드 카드 문법 포스팅은 상한/하한 경계 와일드 카드 문법 포스팅이 될 것이다.
---------------------------------------------------------------------------------
오늘은 여기까지.
[Java] 제네릭과 와일드카드 타입에 대해 쉽고 완벽하게 이해하기(공변과 불공변, 상한 타입과 하한 타입) - MangKyu's Diary
[Java] 제네릭과 와일드카드 타입에 대해 쉽고 완벽하게 이해하기(공변과 불공변, 상한 타입과 하
이번에는 공변과 불공변에 대해서 먼저 알아보고, 이후에 제네릭과 와일드카드에 대해 알아보도록 하겠습니다. 많은 분들이 어려워하는 제네릭인 만큼 쉽게 풀어서 설명하려고 노력했는데, 많
mangkyu.tistory.com
☕ 자바 제네릭의 공변성 & 와일드카드 완벽 이해
자바의 공변성 / 반공변성 제네릭의 와일드카드를 배우기 앞서 선수 지식으로 알고 넘어가야할 개념이 있다. 조금 난이도 있는 프로그래밍 부분을 학습 하다보면 한번쯤은 들어볼수 있는 공변
inpa.tistory.com
'Java' 카테고리의 다른 글
| 자바 - 예외를 반환 할 때, Checked Exception, Unchecked Exception각각 처리 규칙 (0) | 2025.11.13 |
|---|---|
| 자바 - return 하면서 변수를 선언할 수 없음!! (0) | 2025.11.12 |
| 자바 - 오버라이딩 개념 및 예제 (0) | 2025.11.02 |
| 자바 - 커스텀 예외 만들기 (0) | 2025.11.01 |
| 자바 - enum 정리 ( enum 개념 및 예제, enum 매핑 활용 예제 ) (0) | 2025.10.30 |