
제네릭(Generic): 아직 결정되지 않은 타입을 파라미터로 처리하고, 실제 사용할 때 구체적인 타입으로 대체하는 기능.
타입 파라미터 기호: <T>
타입 파라미터는 클래스/인터페이스만 가능 (기본 타입 불가).
// 제네릭 클래스 정의
public class Box<T> {
public T content;
}
// 사용 예제
Box<String> strBox = new Box<>();
strBox.content = "Hello Generics";
Box<Integer> intBox = new Box<>();
intBox.content = 100;
제네릭 타입(Generic Type): 결정되지 않은 타입을 파라미터로 가지는 클래스/인터페이스.
문법:
class 클래스명<T, U, ...> { ... }
interface 인터페이스명<T, U, ...> { ... }
타입을 지정하지 않으면 기본적으로 Object로 취급됨.
// 제네릭 클래스
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value){
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
// 사용
Pair<String, Integer> student = new Pair<>("Alice", 90);
System.out.println(student.getKey() + " : " + student.getValue());
<T> 와 같은 타입 매개변수 명시.// 제네릭 메소드
public class Util {
public static <T> Box<T> boxing(T t) {
Box<T> box = new Box<>();
box.content = t;
return box;
}
}
// 사용
Box<String> strBox = Util.boxing("Hello");
Box<Integer> intBox = Util.boxing(123);
<T extends 상위타입>public class CompareUtil {
public static <T extends Number> boolean compare(T t1, T t2) {
return t1.doubleValue() == t2.doubleValue();
}
}
// 사용
System.out.println(CompareUtil.compare(10, 10)); // true
System.out.println(CompareUtil.compare(3.14, 3.14)); // true
// System.out.println(CompareUtil.compare("a", "b")); // 오류 (Number 타입 아님)
? (와일드카드): 범위 내 모든 타입 가능.
용도: 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 유연성 확보.
세 가지 방식:
<?> : 모든 타입 허용<? extends 상위타입> : 상위 타입 및 하위 클래스 허용<? super 하위타입> : 하위 타입 및 상위 클래스 허용public static void printList(List<?> list) {
for(Object obj : list) {
System.out.println(obj);
}
}
List<String> strList = Arrays.asList("A", "B", "C");
List<Integer> intList = Arrays.asList(1, 2, 3);
printList(strList); // 가능
printList(intList); // 가능