[Java] 제네릭 - 2
2024. 2. 19. 15:29ㆍMemorizing/Java
728x90
본 포스팅에서는 제네릭에서 유연성 캐스팅에 유연성을 더해주는 와일드카드에 대해 다룹니다.
정의
와일드카드는 아래와 같이 타입 변수를 지정할 때, 상속 관계를 어떤 방식으로 지정할지에 대해 "?"를 사용하여 지정하는 것을 말합니다.
1. <? extends T> : T와 그 자손들만 사용 가능
2. <? super T> : T와 그 조상들만 가능
3. <?> : 제한 없음
와일드카드 도입 이유
기본적으로 자바의 타입(기본형 타입, 참조형 타입)은 다운, 업 캐스팅을 지원합니다. 예제코드는 아래와 같습니다.
// 업캐스팅(공변성)
Object[] Covariance = new Integer[10];
// 다운캐스팅(반공변성)
Integer[] Contravariance = (Integer[]) Covariance;
하지만 제네릭은 아래와 같은 상황에서 다운,업 캐스팅을 지원하지 않습니다.
public static void print(List<Object> arr) {
for (Object e : arr) {
System.out.println(e);
}
}
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3);
print(integers); // ! Error
}
따라서 아래와 같이 메소드 오버로딩을 작성해주어야합니다. 하지만, 이는 매우 비효율적입니다.
public static void print(List<Integer> arr) {
}
public static void print(List<Double> arr) {
}
public static void print(List<Number> arr) {
}
...
와일드카드의 상속
와일드 카드의 상속 중 "<? extends T> "케이스의 예제코드만 보도록 하겠습니다.
아래와 같이 MyArrayList를 정의합니다. 아래와 같이 코드를 정의하면, Number의 하위 클래스를 모두 받을 수 있습니다. 따라서 Integer 참조형 변수를 타입으로 넣어도 업캐스팅이 잘 동작하는 것을 알 수 있습니다.
class MyArrayList<T> {
Object[] element = new Object[5];
int index = 0;
// 외부로부터 리스트를 받아와 매개변수의 모든 요소를 내부 배열에 추가하여 인스턴스화 하는 생성자
public MyArrayList(Collection<? extends T> in) {
for(T elem : in) {
element[index++] = elem;
}
}
// ...
}
public static void main(String[] args) {
// MyArrayList의 제네릭 T 타입은 Number
MyArrayList<Number> list;
// MyArrayList 생성하기
Collection<Integer> col = Arrays.asList(1, 2, 3, 4, 5);
list = new MyArrayList<>(col);
// MyArrayList 출력
System.out.println(list); // [1, 2, 3, 4, 5]
}
'Memorizing > Java' 카테고리의 다른 글
[QueryDSL] 최신! 환경설정 (3) | 2024.03.06 |
---|---|
[Java] 초간단! 쿠키, 세션, 토큰 (0) | 2024.02.29 |
[Java] 제네릭 - 1 (0) | 2024.02.19 |
[Java] 프로세스와 스레드 - 4 (1) | 2024.02.17 |
[Java] 프로세스와 스레드 - 3 (0) | 2024.02.17 |