
클래스 옆에 < T > 를 붙이면 지네릭 클래스가 됨.
class Box<T>{
T item;
void setItem(T item) {this.item = item;}
T getItem();
}
이 의미는 만약 아래와 같이 사용하게 된다면,
Box<String> b = new Box<String>();
T 타입을 String 으로 지정해 줬으므로
class Box{
String item;
void setItem(String item) {this.item = item;}
String getItem();
}
이와 같이 정의된 것으로 됨.
class FruitBox<T extends Fruit> {
ArrayList<T> list = new ArrayList<T>();
...
}
다음과 같이 지네릭 타입에 'extends' 를 사용하면, 특정 타입의 자손들만 대입할 수 있게 제한할 수 있음
만일 클래스가 아니라 인터페이스를 구현해야 한다는 제약이 필요하다면 마찬가지로 'extends' 사용
클래스의 자손이면서 인터페이스도 구현해야 한다면 아래와 같이 '&' 기호로 사용
class FruitBox<T extends Fruit & Eatable> {...}
와일드 카드는 어떠한 타입도 될 수 있고, '?'로 표현함.
< ? extends T > 와일드 카드의 상한 제한. T와 그 자손들만 가능
< ? super T > 와일드 카드의 하한 제한. T와 그 조상들만 가능
< ? > 제한 없음. 모든 타입이 가능
이를 이용하면 지네릭 클래스가 아닌 클래스의 스태틱 메서드에 지네릭 타입의 클래스를 선언이 가능하게 됨.
메서드의 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라고 함.
static <T> void sort(List<T> list, <Comparator<? super T> c)
static 멤버에는 타입 매개변수를 사용할 수 없지만, 위와 같이 static 메서드에 지네릭 타입을 선언하고 사용하는 것은 가능.
컴파일러는 지네릭 타입을 이용해 소스파일을 체크하고 필요한 곳에 형변환을 넣어줌. 그리고 지네릭 타입을 제거.
즉 컴파일 된 파일에는 지네릭 타입에 대한 정보가 없음
참고 : <Java의 정석>