무제한 와일드카드(Unbounded Wildcards)
무제한 와일드카드(Unbounded Wildcard)는 <?> 형식을 사용하여 특정 타입에 구애받지 않는 모든 참조 타입(기본타입제외란 뜻)을 나타냅니다. 이는 주로 제네릭 메서드나 클래스에서 타입을 일반화하여 사용할 때 유용합니다. 무제한 와일드카드는 컬렉션에서 읽기 작업은 가능하지만, 타입 안전성을 보장할 수 없기 때문에 삽입 작업은 제한됩니다.
import java.util.ArrayList;
import java.util.List;
public class UnboundedWildcardExample {
// 무제한 와일드카드를 사용하는 메서드
public static void printList(List<?> list) {
for (Object elem : list) {
System.out.println(elem);
}
}
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
// 무제한 와일드카드를 사용하여 리스트 출력
printList(stringList);
printList(intList);
// 무제한 와일드카드 리스트에 요소 삽입 시도 (컴파일 오류)
// list.add("Orange"); // 오류 발생
}
}
public static void printList(List<?> list) {
for (Object elem : list) {
System.out.println(elem);
}
}
무제한 와일드카드 메서드 정의:
- List<?>는 불특정 타입의 요소를 가진 리스트를 의미합니다.
- 메서드 내에서 리스트의 요소를 읽을 수 있지만, 삽입할 수는 없습니다.
List<String> stringList = new ArrayList<>();
stringList.add("Apple");
stringList.add("Banana");
stringList.add("Cherry");
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
// 무제한 와일드카드를 사용하여 리스트 출력
printList(stringList);
printList(intList);
메서드 호출:
무제한 와일드카드에서 삽입이 안 되는 이유
무제한 와일드카드를 사용하는 리스트에 요소를 삽입할 수 없는 이유는 타입 안전성을 보장할 수 없기 때문입니다. List<?>는 어떤 타입의 리스트인지 정확히 알 수 없으므로, 삽입할 타입을 확정할 수 없습니다.
List<?> list = new ArrayList<String>();
list.add("Hello"); // 컴파일 오류: 안전하지 않음
예를 들어, 다음과 같은 상황을 생각해볼 수 있습니다:
- list는 String 타입의 리스트일 수 있지만, List<?>로 선언되어 있어 어떤 타입의 리스트인지 알 수 없습니다.
- 따라서 "Hello" (String 타입)를 삽입하려 하면 타입 불일치가 발생할 수 있습니다.
요약
- 무제한 와일드카드 (<?>): 불특정 타입의 요소를 나타내며, 모든 타입을 허용합니다.
- 읽기 전용: 무제한 와일드카드는 주로 컬렉션에서 요소를 읽을 때 사용됩니다.
- 삽입 불가: 타입 안전성을 보장할 수 없기 때문에 무제한 와일드카드를 사용하는 컬렉션에 요소를 삽입할 수 없습니다.
상한 와일드카드(Upper Bounded Wildcard)
상한 와일드카드(Upper Bounded Wildcard)는 <? extends T> 형식을 사용하여 특정 타입의 하위 타입들을 허용합니다. 이는 컬렉션에서 요소를 읽는 데 유용하지만, 요소를 삽입하는 데는 적합하지 않습니다. 상한 와일드카드를 사용하는 컬렉션에 요소를 삽입할 수 없는 이유는 타입 안전성을 보장하기 위해서입니다.
import java.util.ArrayList;
import java.util.List;
public class UpperBoundedWildcardExample {
// 상한 와일드카드를 사용하는 메서드
public static void processNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
List<Double> doubleList = new ArrayList<>();
doubleList.add(1.1);
doubleList.add(2.2);
doubleList.add(3.3);
// 상한 와일드카드를 사용하여 리스트 처리
processNumbers(intList);
processNumbers(doubleList);
// 상한 와일드카드 리스트에 요소 삽입 시도 (컴파일 오류)
// list.add(4); // 오류 발생
}
}
public static void processNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
상한 와일드카드 메서드 정의 :
- List<? extends Number>는 Number 타입 또는 그 하위 타입의 리스트를 의미합니다.
- 리스트에서 요소를 읽을 때는 안전합니다. 모든 요소는 Number 타입이므로 Number 타입으로 처리할 수 있습니다.
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
List<Double> doubleList = new ArrayList<>();
doubleList.add(1.1);
doubleList.add(2.2);
doubleList.add(3.3);
// 상한 와일드카드를 사용하여 리스트 처리
processNumbers(intList);
processNumbers(doubleList);
메서드 호출 :
상한 와일드카드에서 삽입이 안 되는 이유
상한 와일드카드를 사용하는 리스트에 요소를 삽입할 수 없는 이유는 컴파일러가 타입 안전성을 보장할 수 없기 때문입니다.
List<? extends Number>는 Number의 하위 타입을 포함할 수 있습니다. 하지만 구체적으로 어떤 타입인지 알 수 없으므로, 안전하게 삽입할 수 있는 타입을 알 수 없습니다.
List<? extends Number> numberList = new ArrayList<Integer>();
numberList.add(1.5); // 컴파일 오류: 안전하지 않음
예를 들어, 다음과 같은 상황을 생각해볼 수 있습니다:
- numberList는 Integer 타입의 리스트일 수 있지만, 상한 와일드카드로 선언되어 있어 Double 또는 Float 등의 다른 하위 타입일 수도 있습니다.
- 따라서 1.5 (double 타입)를 삽입하려 하면 타입 불일치가 발생할 수 있습니다.
요약
- 상한 와일드카드 (<? extends T>): T 타입 또는 그 하위 타입을 허용합니다.
- 삽입 불가: 타입 안전성을 보장할 수 없기 때문에 상한 와일드카드를 사용하는 컬렉션에 요소를 삽입할 수 없습니다.
- 읽기 전용: 상한 와일드카드는 주로 컬렉션에서 요소를 읽을 때 사용됩니다.
상한 와일드카드는 특정 타입의 하위 타입들을 처리할 때 유용하지만, 타입 안전성을 위해 요소 삽입은 제한됩니다.
하한 와일드카드(lower bounded wildcard)
하한 와일드카드(lower bounded wildcard)는 <? super T> 형식을 사용하여 특정 타입 이상의 모든 타입을 허용합니다. 이는 삽입(insertion) 작업에서 유용합니다. 하한 와일드카드를 사용하면, 해당 타입 또는 그 상위 타입의 요소들을 컬렉션에 삽입할 수 있습니다.
import java.util.ArrayList;
import java.util.List;
public class LowerBoundedWildcardExample {
// 하한 와일드카드를 사용하는 메서드
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i); // Integer 타입의 요소 삽입
}
}
public static void main(String[] args) {
List<Number> numberList = new ArrayList<>();
addNumbers(numberList);
System.out.println(numberList); // 출력: [1, 2, 3, 4, 5]
List<Object> objectList = new ArrayList<>();
addNumbers(objectList);
System.out.println(objectList); // 출력: [1, 2, 3, 4, 5]
}
}
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i); // Integer 타입의 요소 삽입
}
}
하한 와일드카드 메서드 정의
- List<? super Integer>는 Integer 타입 또는 그 상위 타입의 요소를 허용하는 리스트를 의미합니다.
- 따라서 Integer, Number, Object 타입의 리스트에 Integer 타입의 요소를 삽입할 수 있습니다.
List<Number> numberList = new ArrayList<>();
addNumbers(numberList);
System.out.println(numberList); // 출력: [1, 2, 3, 4, 5]
List<Object> objectList = new ArrayList<>();
addNumbers(objectList);
System.out.println(objectList); // 출력: [1, 2, 3, 4, 5]
메서드 호출
- numberList와 objectList는 각각 Number와 Object 타입의 리스트입니다.
- addNumbers 메서드는 numberList와 objectList에 Integer 요소들을 삽입할 수 있습니다.
요약
- 하한 와일드카드 (<? super T>): T 타입 또는 그 상위 타입을 허용합니다.
- 삽입 가능: 하한 와일드카드를 사용하면 해당 타입 또는 그 상위 타입의 요소를 컬렉션에 삽입할 수 있습니다.
- is-a 관계: 하한 와일드카드는 상위 타입과의 is-a 관계를 활용하여 요소 삽입을 가능하게 합니다.
import java.util.ArrayList;
import java.util.List;
public class WildcardExample {
public static void main(String[] args) {
List<?> wildcardList = new ArrayList<Integer>();
// null 삽입은 허용됩니다.
wildcardList.add(null);
// 다른 객체 삽입 시도 (컴파일 오류 발생)
// wildcardList.add("Hello"); // 컴파일 오류
// wildcardList.add(123); // 컴파일 오류
System.out.println("List contains: " + wildcardList);
}
}
List는 동일한 데이터 타입의 엘리먼트여야 하는데 <?> 는 알 수 없는 타입의 List 이기 때문에
null은 아무것도 참조안한단 거라서 삽입 가능하다.
'Java' 카테고리의 다른 글
Type Erasure(타입 소거) (0) | 2024.07.18 |
---|---|
@ 어노테이션 (Annotation) (0) | 2024.07.18 |
자바 ArrayList 특징 & 사용법 정리 (5) | 2024.07.16 |
동일성(Identity)과 동등성(Equality) (0) | 2024.07.16 |
캐시(Cache)와 캐싱(Caching) (0) | 2024.07.16 |