정적 제네릭 메서드
아래 소스코드의 1,2 번의 정적 제네릭 메서드 중 어떤 것이 정상 작동할까요?
public class Generics<T> {
public static void print(T t) {} // 1번
public static <T> void print(T t) {} // 2번
}
1번은 컴파일 에러가 발생하고 2번은 정상작동 합니다.
1번은 클래스 레벨에서 제네릭을 사용한다는 의미입니다. 제네릭 메서드에
제네릭 메서드는 호출 시에 파라미터 타입을 지정하기 때문에 2번이 가능합니다.
주의해야 할 점은 Generics 클래스에 지정한 제네릭 타입<T>와 2번 제네릭 메서드에서 지정한 제네릭 타입<T>는 서로 다릅니다.
2번은 메서드 레벨에서 제네릭을 사용한다는 의미이며 클래스 제네릭 타입<T>와 헷갈리므로 보통 겹치지 않게 다른 문자(ex. <S>, <E> 등)를 사용합니다.
타입 파라미터의 상속 관계
아래 소스코드는 컴파일 에러가 발생하지 않습니다.
public static void main(String[] args) {
Integer integer = 100;
Number number = integer;
}
Integer 클래스는 Number라는 추상 클래스를 상속하고 있기에 Number 인스턴스에 대입이 가능합니다.
하지만 아래 소스코드는 정상작동하지 않습니다.
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
List<Number> numbers = integers;
}
List<Number> numbers = integers; 부분에서 컴파일 에러가 발생합니다.
제네릭에서 타입 파라미터 내 클래스는 상속 관계에 전혀 영향을 주지도, 받지도 않습니다.
위의 컴파일 에러를 경계 타입 파라미터(Boundary Type Parameter)를 사용하여 해결할 수 있습니다.
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
List<? extends Number> numbers = integers;
}
List<? extends Number>에서 ?의 의미는 와일드카드이며 Number 클래스를 상속받은 모든 클래스만 사용가능합니다.
컴파일 에러가 발생하지 않습니다.