제네릭 클래스를 정의할 때, 혹은 제네릭 변수를 선언할 때 (매개변수 포함), 그리고 제네릭 메소드를 정의할 때, 제네릭 매개변수 T 를 정의할 수 있는데, 범위에 따라서 알아보기로 하겠습니다.


제네릭 클래스를 정의할 때

<T>

한 개의 클래스가 T 로 정해지면 그 클래스만 가능함


<T, U>

두 개의 클래스를 각각 T 와 U 로 정하고 그 클래스들만 가능함


<T extends 클래스명>

클래스명을 상속하는 모든 하위 클래스들 중 하나의 클래스가 T 로 정해지면 그 클래스만 가능함


제네릭 변수 (매개변수 포함) 혹은 제네릭 메소드를 정의할 때

<T>

한 개의 클래스가 T 로 정해지면 그 클래스만 가능함


<T extends 클래스명>

클래스명을 상속하는 모든 하위 클래스들 중 하나의 클래스가 T 로 정해지면 그 클래스만 가능함


<T super 클래스명>

클래스명이 상속하는 모든 상위 클래스들 중 하나의 클래스가 T 로 정해지면 그 클래스만 가능함


<?>

Object 를 상속하는 모든 하위 클래스들만 가능 (처음 정해진 것이 아닌 다른 클래스도 다시 올 수 있음)


<? extends 클래스명>

클래스명을 상속하는 모든 클래스들만 가능 (처음 정해진 것이 아닌 다른 클래스 중에서 클래스명을 상속한다면 다시 올 수 있음)


<? super 클래스명>

클래스명이 상속하는 모든 클래스들만 가능 (처음 정해진 것이 아닌 다른 클래스 중에서 클래스명이 상속한다면 다시 올 수 있음)


제네릭 변수를 선언할 때 <? extends 클래스명> 구문에서 따로 클래스명이 final 클래스인지 아닌지 컴파일 타임에서 체크하지 않습니다. 그 인스턴스 변수의 메소드를 사용하고자 할 때 (매개변수로 안전하지 않은 타입을 넘길 때)


List<? extends String> list = new ArrayList<String>(); // 컴파일 타임에서 에러 체크 안함

list.add("hello"); // 컴파일 에러 발생


위의 코드를 보면, 첫 라인에서 변수를 선언시에는, 컴파일 에러가 나지 않습니다. (String 이 final 클래스라서, 상속이 불가한데도 에러 체크를 하지 않음) 단, 그 다음 라인에서 add 같은 메소드를 호출할 때는, 컴파일 에러를 발생 시킵니다.

by kkikkodev 2015. 7. 31. 22:29