class ClassName<Type1, Type2, Type3, ... TypeN>{ }
class ClassName<Type1, Type2, Type3 ... TypeN> extends SuperClass<Type1, Type2, ...TypeN> { }
규칙
제네릭을 사용하면서 흔하게 일어나는 실수
Vehicle: 움직이는 이동 수단의 상위 추상 클래스 Sedan: Vehicle을 상속받아서 구현한 승용차 클래스 Truck: Vehicle을 상속받아서 구현한 트럭 클래스
MyList<Sedan> sedanList = new MyList<>();
MyList<Truck> truckList = new MyList<>();
MyList<Vehicle> vehicleList = sedanList; // 컴파일 에러
MyList<Object> ObjectList = truckList; // 컴파일 에러.
제네릭 타입 파라미터는 컬렉션 클래스 등에서 처리할 객체를 명확히 하기 위한것으로 상속까지 고려된 것이 아님.
instanseof는 제네릭에서 정의한 타입까지 비교해서 확인하지 않는다.
System.out.println(myList instanceof ArrayList);
System.out.println(stringList instanceof ArrayList<String>); // 컴파일 에러
컴파일 오류를 해결하는 첫번째.
System.out.println(stringList instanceof ArrayList);
System.out.println(integerList instanceof ArrayList);
컴파일 오류를 해결하는 두번째. 와일드카드를 선언.
System.out.println(stringList instanceof ArrayList<?>);
System.out.println(integerList instanceof ArrayList<?>);
제네릭을 이용해서 메서드를 설계할 때 고려해야 할점
제네릭 타입 참조(Type Reference)
public static <K, V> Map<K, V> sorting(Map<K, V> map) {
// ...
return map;
}
// 호출 예제
Map<String, String> prop = new HashMap<>();
Map<String, String> sortedProp = GenericUtil.<String, String>sorting(prop);
JVM에서 제네릭 처리
와일드카드(?)
의미
모든 객체는 Object와 상속관계에 있기 때문에 모든걸 포용하는 타입으로 생각할 수 있지만, 제네릭의 타입파라미터의 목적은 사용할 클래스 타입을 명확히 하기 위함이기때문에 컴파일 시 오류가 발생한다.
void printCollection(Collection<Object> c) {
for(Object e : c) {
System.out.println(e);
}
}
List<Object> objList = new ArrayList<Object>();
List<String> stringList = new ArrayList<String>();
printCollection(objList); // 정상 컴파일됨.
printCollection(stringList); // 컴파일 에러가 발생함.
타입 파라미터와의 차이
와일드카드에서 특정타입으로 제한하고 싶을때.
특정타입으로 제한하는 것을 바운드 타입 파라미터라고 한다.
extends를 이용한 제한.
// Vehicle을 상속받은 모든 클래스를 제네릭으로 사용할 수 있도록 한다.
public class GenericBoundExample<T extends Vehicle> {
}
void printCollection(Collection<? extends Vehicle> c) {
}
타입을 하나 이상 지정할 수 있다.
<T extends A & B & C>
<T extends Class1 & Interface1 & Interface2>
super를 이용한 제한.
// Integer, Number, Object만 가능.
public static void addNumbers(List<? super Integer> list) { }
정리
제네릭 제약조건
다이아몬드 연산자
var