제네릭은 클래스 , 인터페이스 , 메서드가 다양한 타입을 일반화해서 처리할 수 있도록 해주는 기능이다.
타입을 매개변수로 지저하여 코드 작성시 특정 타입을 나중에 사용자가 지정할 수 있게 된다.
제네릭 클래스
// T는 타입 매개변수로, 나중에 구체적인 타입으로 지정됨
class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
// Integer 타입을 지정한 Box
Box<Integer> integerBox = new Box<>();
integerBox.setValue(123);
System.out.println(integerBox.getValue()); // 123
// String 타입을 지정한 Box
Box<String> stringBox = new Box<>();
stringBox.setValue("Hello, world!");
System.out.println(stringBox.getValue()); // Hello, world!
}
}
제네릭 메서드
public class GenericMethodExample {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3};
String[] stringArray = {"A", "B", "C"};
printArray(intArray); // 1 2 3
printArray(stringArray); // A B C
}
}
제네릭 인터페이스
interface Printer<T> {
void print(T t);
}
class StringPrinter implements Printer<String> {
public void print(String t) {
System.out.println("String: " + t);
}
}
public class GenericInterfaceExample {
public static void main(String[] args) {
Printer<String> printer = new StringPrinter();
printer.print("Hello, World!");
}
}
제한된 제네릭
타입 매개변수에 제한을 둘 수 있다. ex) 타입이 Number 클래스를 상속한 모든 타입에 대해서만 동작
class Box<T extends Number> { // T는 Number 또는 그 하위 클래스만 가능
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> integerBox = new Box<>();
integerBox.setValue(10);
System.out.println(integerBox.getValue()); // 10
// Box<String> stringBox = new Box<>(); // 컴파일 에러! String은 Number의 하위 클래스가 아님
}
}
와일드 카드
와일드 카드는 제네릭 타입을 유연하게 사용할 때 유용하다.
- ? (Unbounded Wildcard) : 어떤 타입도 허용
// 와일드카드 사용
public class Main {
public static void printList(List<?> list) { // 모든 타입의 List를 받을 수 있음
for (Object item : list) {
System.out.println(item);
}
}
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3);
List<String> strList = List.of("A", "B", "C");
printList(intList); // 1, 2, 3
printList(strList); // A, B, C
}
}
- ? extends T (Upper Bounded Wildcard) : T와 T의 하위 클래스만 허용
public double sumList(List<? extends Number> list) {
double sum = 0;
for (Number n : list) {
sum += n.doubleValue();
}
return sum;
}
- ? super T (Lower Bounded Wildcard) : T와 T의 상위 클래스만 허용
public void addToList(List<? super Integer> list) {
list.add(1); // Integer 또는 상위 클래스에 추가 가능
}

