본문 바로가기
Java Study

제네릭 타입 매개변수(T)와 와일드카드(?)의 역할

by xogns93 2024. 8. 19.

 제네릭 타입 매개변수(T)와 와일드카드(?)의 역할을 비교

 

 

제네릭 타입 매개변수 (T)

  • 정의: T제네릭 클래스나 메서드에서 타입을 일반화하여 사용할 수 있도록 만드는 타입 매개변수입니다. T는 특정 타입을 나타내며, 제네릭 클래스를 인스턴스화할 때 또는 제네릭 메서드를 호출할 때 그 타입이 결정됩니다.
  • 용도: T를 사용하면 메서드나 클래스가 여러 타입을 지원할 수 있지만, 그 타입이 명확하게 지정되며, 코드 내부에서 일관되게 사용할 수 있습니다.
  • 상한 또는 하한 바운드 사용: T extends Number와 같이 특정 타입의 상한 바운드(또는 하한 바운드)를 설정하여 타입 매개변수를 제한할 수 있습니다.

예시:

class Box<T> { // T는 Box가 사용되는 동안 고유한 타입
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

Box<Integer> intBox = new Box<>(); // T는 Integer로 설정
intBox.setItem(10);
Integer item = intBox.getItem(); // T가 Integer로 지정되었으므로 반환 타입도 Integer

와일드카드 (?)

  • 정의: ?는 제네릭 타입을 사용할 때 타입에 대한 제약을 완화하여 다양한 타입을 허용하기 위한 와일드카드입니다. 와일드카드는 T와 달리 타입 매개변수가 고정되지 않고, 특정 범위 내의 불특정 타입을 나타냅니다.
  • 용도: 와일드카드를 사용하면 제네릭 메서드나 클래스를 호출할 때, 특정 타입으로 고정하지 않고 더 유연하게 사용할 수 있습니다. 하지만 T와 달리 와일드카드를 사용하면 타입을 고정할 수 없으므로, 내부에서 그 타입을 직접 사용하는 데는 제한이 있습니다.
  • 상한 또는 하한 바운드 사용: ? extends Number, ? super Integer와 같이 상한 또는 하한 바운드를 설정하여 와일드카드가 허용하는 타입의 범위를 제한할 수 있습니다.

예시:

public void printList(List<? extends Number> list) { // 와일드카드 사용
    for (Number n : list) { 
        System.out.println(n);
    }
}

List<Integer> intList = Arrays.asList(1, 2, 3);
List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3);

printList(intList);   // 가능: Integer는 Number의 서브클래스
printList(doubleList); // 가능: Double도 Number의 서브클래스

차이점 요약

  1. 타입 고정 vs 유연성:
    • T는 제네릭 클래스나 메서드를 정의할 때 타입을 고정하고, 그 타입을 여러 곳에서 일관되게 사용할 수 있습니다. 따라서 타입 안전성이 높습니다.
    • ?는 타입을 고정하지 않고, 그 범위 내에서 불특정 타입을 받아들일 수 있어 더 유연하지만, 내부에서 특정 타입으로 사용하는 데 제한이 있습니다.
  2. 제네릭 클래스/메서드 정의 vs 호출:
    • T는 주로 제네릭 클래스나 메서드를 정의할 때 사용됩니다. 타입 매개변수로 사용자가 지정한 타입이 코드 전체에서 일관되게 적용됩니다.
    • ?는 제네릭 클래스나 메서드를 사용할 때, 즉 제네릭 타입을 인스턴스화하거나 메서드를 호출할 때 사용되어 타입을 유연하게 관리할 수 있습니다.
  3. 바운드 사용 시 차이:
    • T extends NumberT가 반드시 Number나 그 서브클래스여야 하며, T는 해당 타입으로 고정됩니다.
    • ? extends NumberNumber의 서브클래스에 해당하는 어떤 타입이든 받을 수 있지만, 그 타입이 정확히 무엇인지는 고정되지 않습니다. 따라서 내부에서 타입을 고정해서 사용할 수 없습니다.

결론

T?는 비슷해 보일 수 있지만, T는 고정된 타입을 의미하며, 제네릭 클래스나 메서드 정의 시 사용됩니다. 반면 ?는 불특정 타입을 의미하며, 타입을 유연하게 관리할 필요가 있을 때 사용됩니다. 이는 제네릭 프로그래밍에서 중요한 차이점입니다.