우선 용어정의 부터 하자.

 용어  사용 예
 매개화 변수타입(Parameterized type) List<String> 
 실 타입 매개변수(Actual type parameter) String 
 제네릭 타입(Generic type) List<E> 
 형식 타입 매개변수(Formal type parameter)
 언바운드 와일드 카드 타입
(Unbounded wildcard type)
 List<?>
 원천 타입(Raw type)  List
 바운드 타입 매개변수
(Bounded type parameter)
 <E extends Number>
 재귀적 타입 바운드(Recursive type bound) <T extends Comparable<T>> 
 바운드 와일드 카드 타입
(Bounded wildcard type)
List<? extends Number> 
 제네릭 메소드(Generic method) static <E> List<E> asList(E[] a) 
 타입 토큰(Type token) String.class 

하나 이상의 타입 매개 변수를 선언하고 있는 클래스나 인터페이스를 제네릭 클래스, 또는 제네릭 인터페이스라고 부른다. 각 제네릭 타입에서는 매개변수화 타입들을 정의한다.
정의 하는 법은 클래스나 인터페이스 이름 다음에 <> 를 사용해서 매개변수들을 나타내는데. 실 타입 매개변수들은 제네릭 타입의 형식 타입 매개변수와 각각 대응된다. 
각 제네릭 타입에서는 raw 타입을 정의하는데 원천 타입이란 실 타입 매개변수가 없이 사용되는 제네릭 타입 이름을 말한다. (ex - List 이렇게)
이 경우 타입 매개변수를 주지 않고 커렉션 타입이나 다른 제네릭 타입을 사용할 수 있지만 그렇게 해서는 안된다. 왜냐면 원천 타입을 사용하면 제네릭의 장점인 타입 안전과 표현력 모두를 포기하는 것이기 때문이다. 
이걸 막지 않은 이유는 호환성 때문인데 새 코드에서는 되도록 원천 타입을 사용해선 안된다.

간단한 예로  List와 같은 원천 타입을 ㅅ용하면 타입의 안정성을 상실하지만 List<Object>과 같은 매개변수 타입을 사용하면 그렇지 않다.

향후에 작성하는 새 코드에는 원천 타입을 사용하지 않는다는 규칙에도 두가지 예외가 있는데 런타임 시에는 제네릭 타입의 정보가 없어진다는 것 때문에 가능하다.
첫 번째로 원천 타입은 클래스 리터럴의 형태로 사용해야 한다. 자바 명세서에 보면 원천 타입을 매겨변수화 타입과 사용할 수 없다. 즉 String[].class, int.class는 모두 적법하지만 , List<String>.class와 List<?>.class는 허용되지 않는다.
두 번째로 instanceof 연산자와 관련된 것이다. 제네릭 타입의 정보는 런타임 시에 없어지므로 언바운드 와일드 카드 타이이 아닌 다른 매개변수화 타입에 대해 instanceof 연산자를 사용할 수 없다.
Posted by 서오석
,