Java에서 제네릭(Generic)은 클래스, 인터페이스, 메서드 등에 사용할 수 있는 타입 매개변수화 기법을 말한다.
제네릭을 사용하면 컴파일 시 타입을 체크할 수 있으며, 코드의 재사용성을 높이고, 타입 안정성을 보장할 수 있다.
제네릭은 자바 5에서 도입되었으며, 주로 컬렉션 프레임워크에서 많이 사용된다.
제네릭의 주요 특징
타입 안전성(Type Safety) 보장
컴파일 시점에 타입을 체크하여 런타임 에러를 줄일 수 있다
타입 캐스팅 제거
제네릭을 사용하면 불필요한 타입 캐스팅을 제거할 수 있다
코드 재사용성 증가
다양한 타입에 대해 동일한 코드를 사용할 수 있다
제네릭의 기본 사용법
제네릭 클래스
제네릭 클래스는 클래스 선언 시 타입 매개변수를 사용하여 정의할 수 있다
다음은 제네릭 클래스를 사용하는 예제이다
public class Box<T> {
    private T item;
    public void setItem(T item) {
        this.item = item;
    }
    public T getItem() {
        return item;
    }
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setItem("Hello");
        System.out.println(stringBox.getItem());
        Box<Integer> integerBox = new Box<>();
        integerBox.setItem(123);
        System.out.println(integerBox.getItem());
    }
}
위의 예제에서 Box<T>는 제네릭 클래스이다
T는 타입 매개변수로, Box 클래스 내부에서 실제 타입으로 대체된다
제네릭 메서드
제네릭 메서드는 메서드 선언에 타입 매개변수를 사용할 수 있다
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, 4, 5};
        String[] stringArray = {"A", "B", "C", "D", "E"};
        printArray(intArray);
        printArray(stringArray);
    }
}
위의 예제에서 printArray 메서드는 제네릭 메서드이다
T는 메서드의 타입 매개변수이다
제네릭 인터페이스
제네릭 인터페이스는 인터페이스 선언 시 타입 매개변수를 사용할 수 있다
public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}
class OrderedPair<K, V> implements Pair<K, V> {
    private K key;
    private V value;
    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    @Override
    public K getKey() { return key; }
    @Override
    public V getValue() { return value; }
    public static void main(String[] args) {
        Pair<String, Integer> p1 = new OrderedPair<>("One", 1);
        Pair<String, String> p2 = new OrderedPair<>("Hello", "World");
        System.out.println("Pair 1: " + p1.getKey() + " = " + p1.getValue());
        System.out.println("Pair 2: " + p2.getKey() + " = " + p2.getValue());
    }
}
위의 예제에서 Pair<K, V>는 제네릭 인터페이스이며, OrderedPair<K, V>는 이를 구현한 제네릭 클래스이다
제네릭 타입 제한 (Bounded Type Parameters)
제네릭 타입에 특정 타입만 허용하도록 제한할 수 있다
이는 extends 키워드를 사용하여 구현할 수 있다
public class BoundedTypeParameterExample {
    public static <T extends Number> void printNumber(T number) {
        System.out.println("Number: " + number);
    }
    public static void main(String[] args) {
        printNumber(123);      // Integer
        printNumber(45.67);    // Double
        // printNumber("123"); // 컴파일 오류
    }
}
위의 예제에서 T extends Number는 T가 Number 클래스 또는 그 하위 클래스여야 함을 의미한다
와일드카드(Generic Wildcards)
와일드카드는 제네릭 타입을 보다 유연하게 사용할 수 있도록 도와준다
무제한 와일드카드 <?>
상한 경계 와일드카드 <? extends Type>
하한 경계 와일드카드 <? super Type>
와일드카드 예제
import java.util.List;
import java.util.ArrayList;
public class WildcardExample {
    public static void printList(List<?> list) {
        for (Object elem : list) {
            System.out.print(elem + " ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);
        intList.add(3);
        List<String> stringList = new ArrayList<>();
        stringList.add("A");
        stringList.add("B");
        stringList.add("C");
        printList(intList);
        printList(stringList);
    }
}
위의 예제에서 printList 메서드는 무제한 와일드카드를 사용하여 모든 타입의 리스트를 인자로 받을 수 있다
요약
제네릭은 자바에서 타입을 매개변수화하여 코드의 재사용성을 높이고, 컴파일 시 타입 체크를 통해 타입 안전성을 보장하는 강력한 기법이다
제네릭 클래스, 제네릭 메서드, 제네릭 인터페이스, 와일드카드 등 다양한 기능을 통해 복잡한 타입 관계를 표현할 수 있다
이를 적절히 사용하면 더 안전하고 유지보수하기 쉬운 코드를 작성할 수 있다
'Job Interview Prep' 카테고리의 다른 글
| ktlint 자동적용 안 되는 경우 해결법 (0) | 2024.06.02 | 
|---|---|
| String과 StringBuilder, StringBuffer의 차이 (0) | 2024.05.31 | 
| Java volatile / synchronized (0) | 2024.05.31 | 
| JavaBean (1) | 2024.05.31 | 
| Java의 다형성(Polymorphism) (0) | 2024.05.31 | 
 
  
  
  
                
                
                
                
                
                
                
                                                
                
                
                
  
    