하한 와일드카드
소비자를 위한 ? super T를 알아봅니다
하한 와일드카드은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
하한이 있는 와일드카드
? super T는 하한이 있는 와일드카드입니다. 이는 “T이거나 T의 상위 형식인, 정체를 알 수 없는 어떤 형식”을 의미합니다.
List<? super Integer>는 List<Integer>, List<Number> 또는 List<Object>를 가리킬 수 있습니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> a = new ArrayList<Number>();
List<? super Integer> b = new ArrayList<Object>();
a.add(1);
b.add(2);
System.out.println(a + " " + b);
}
}소비자에게 쓰기
? super Integer를 사용하면 모든 Integer(또는 Integer의 하위 형식)를 안전하게 추가할 수 있습니다.
실제 리스트 형식이 무엇이든 적어도 Integer의 어떤 상위 형식에 해당하는 리스트이므로 Integer는 항상 들어갈 수 있습니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
static void addNumbers(List<? super Integer> dest) {
for (int i = 1; i <= 3; i++) dest.add(i);
}
public static void main(String[] args) {
List<Number> nums = new ArrayList<>();
addNumbers(nums);
System.out.println(nums);
}
}읽으면 Object를 얻습니다
대신 ? super T 리스트에서 읽을 때 컴파일러가 아는 것은 요소가 T의 정체를 알 수 없는 어떤 상위 형식이라는 사실뿐입니다.
읽기에 안전한 유일한 형식은 Object입니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> list = new ArrayList<Number>();
list.add(10);
Object o = list.get(0); // only Object is guaranteed
// Integer i = list.get(0); // would NOT compile
System.out.println(o);
}
}읽기가 제한되는 이유
List<? super Integer>가 실제로는 문자열을 담은 List<Object>일 수 있습니다.
따라서 읽기 결과는 어떤 Object든 될 수 있습니다. 컴파일러는 Integer라고 보장할 수 없으므로 읽기 결과는 Object로만 제공합니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Object> raw = new ArrayList<>();
raw.add("a string");
List<? super Integer> view = raw; // legal: Object is a supertype of Integer
view.add(5);
System.out.println(view.get(0).getClass().getSimpleName());
}
}소비자 사용 사례
메서드가 값을 소비하기만 할 때(값을 쓸 때) ? super T를 사용합니다.
대상 컬렉션을 채우는 메서드가 전형적인 사례입니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
static void fill(List<? super String> dest, int count) {
for (int i = 0; i < count; i++) dest.add("item" + i);
}
public static void main(String[] args) {
List<Object> objs = new ArrayList<>();
fill(objs, 3);
System.out.println(objs);
}
}하위 형식도 추가할 수 있습니다
? super Number를 사용하면 모든 Number와 그 하위 형식을 추가할 수 있습니다. 예를 들면 정수형, 실수형, 긴 정수형이 있습니다.
하한은 리스트가 적어도 Number를 받아들인다는 것을 보장하므로 모든 하위 형식을 넣을 수 있습니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Number> list = new ArrayList<Object>();
list.add(1); // Integer
list.add(2.5); // Double
list.add(3L); // Long
System.out.println(list);
}
}Collections.addAll 방식
JDK는 값을 받아들이는 대상에 하한을 사용합니다. 예를 들어 요소를 대상에 넣는 제네릭 메서드가 그렇습니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
@SafeVarargs
static <T> void addAll(List<? super T> dest, T... items) {
for (T item : items) dest.add(item);
}
public static void main(String[] args) {
List<Object> sink = new ArrayList<>();
addAll(sink, "a", "b", "c");
System.out.println(sink);
}
}super를 사용하는 비교기
실제 사용 사례로 Comparator<? super T>를 사용하면 상위 형식을 대상으로 작성된 비교기도 정렬에 사용할 수 있습니다.
어떤 Object든 toString으로 비교하는 비교기는 문자열 리스트도 정렬할 수 있습니다.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
Comparator<Object> byString = Comparator.comparing(Object::toString);
List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
names.sort(byString); // List<String>.sort accepts Comparator<? super String>
System.out.println(names);
}
}super와 extends는 서로 반대입니다
두 와일드카드는 서로 반대입니다.
? extends T: T로 읽을 수 있지만 쓸 수는 없습니다. 생산자입니다.? super T: T를 쓸 수 있지만 읽을 때는 Object로만 읽을 수 있습니다. 소비자입니다.
이 대칭이 바로 다음에 배울 PECS 규칙의 핵심입니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> consumer = new ArrayList<Number>();
consumer.add(1);
System.out.println("consumer can write: " + consumer);
}
}제한이 다른 형식 사이에서 복사하기
복사 메서드는 두 와일드카드를 한 번에 보여 줍니다. ? extends T에서 읽고 ? super T에 씁니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> void copy(List<? extends T> src, List<? super T> dest) {
for (T t : src) dest.add(t);
}
public static void main(String[] args) {
List<Integer> src = List.of(1, 2, 3);
List<Number> dest = new ArrayList<>();
copy(src, dest);
System.out.println(dest);
}
}와일드카드를 사용하지 말아야 할 때
메서드가 T를 읽기도 하고 쓰기도 한다면 와일드카드를 사용하지 마십시오. 정확한 형식이나 이름이 있는 형식 매개변수를 사용하십시오.
와일드카드는 읽기 전용 또는 쓰기 전용인 경우를 위해 존재합니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> void swapFirstTwo(List<T> list) {
T tmp = list.get(0);
list.set(0, list.get(1));
list.set(1, tmp);
}
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("a", "b"));
swapFirstTwo(list);
System.out.println(list);
}
}빠른 확인
하한에 대한 이해도를 확인해 보십시오.
복습
하한이 있는 와일드카드를 배웠습니다.
? super T는 T의 정체를 알 수 없는 상위 형식을 의미합니다.- T와 그 하위 형식을 쓸 수 있습니다(소비자).
- 읽기 결과는 Object로만 반환됩니다.
? extends T와 정확히 반대되는 역할을 합니다.
다음에는 둘을 연결하는 규칙인 PECS를 살펴봅니다.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<? super Integer> list = new ArrayList<Number>();
list.add(42);
System.out.println("Lower bound recap: " + list);
}
}자주 묻는 질문
“하한 와일드카드” 강의는 무료인가요?
네 — “하한 와일드카드” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“하한 와일드카드”에서 뭘 배우나요?
소비자를 위한 ? super T를 알아봅니다 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“하한 와일드카드” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 상한 와일드카드
- 하한 와일드카드
- PECS 원칙
- API에서 와일드카드 사용