제네릭이란 무엇인가요?
자바에서 제네릭(
Generic) 이란, 클래스 내부에서 사용할 데이터 타입을 외부에서 저장하는 기법을 의미하며, 객체별로 다른 타입의 자료가 저장될 수 있도록 한다.컴파일 타임에 타입을 체크함으로써 코드의 안전성을 높여주는 기능을 가지고 있다.

제네릭은 다이아몬드 연산자라고 하는
<>꺾쇠 괄호 키워드를 사용한다.그리고 이 꺾쇠 괄호 안에 식별자 기호를 지정해 파라미터화할 수 있다.
이것을 마치 메서드가 매개변수를 받아 사용하는 것과 비슷하여 제네릭의 타입 매개변수(parameter) / 타입 변수 라고 부른다.
타입 파라미터 기호 네이밍(암묵적인 규칙)
< T >
타입(Type)
< E >
요소(Element)
< K >
키(Key)
< V >
리턴 값 또는 매핑된 값(Variable)
< N >
숫자(Number)
< S, U, V >
2번째, 3번째, 4번째에 선언된 타입
제네릭을 사용했을 때 이점
컴파일 타임에 강력한 타입 검사를 통해 예외 방지
제네릭이 나오기 전 자바 1.5 이전에는
Object를 사용해 제네릭과 비슷하게 구현했다.이럴 경우 개발자가 일일이 타입 변환을 시도해야 하며, 실수할 가능성이 존재한다.
하지만 제네릭을 사용하면 컴파일 타임에 미리 에러를 잡아주기 때문에 실수를 사전에 방지할 수 있다.
불필요한 캐스팅 제거
제네릭 없이
Object를 사용하면 매번 다운 캐스팅을 통해 객체를 가져와야 한다.제네릭을 사용하면 미리 타입을 지정하여 제한하기 때문에 형 변환의 번거로움을 줄일 수 있다.
변성(variance)
List<Object> objectList = new ArrayList<Integer>();이 코드는 가능할까? Integer는 Object의 하위 타입이지만 컴파일 오류가 발생한다.
Object[] objectArr = new Integer[1];이와 같이 배열에서는 Integer가 Object의 하위 타입이 성립이 된다. 이를 공변이라 한다.
하지만 제네릭 같은 경우는 Object와 Integer를 서로 관계가 없다고 보는데 이를 무공변 또는 불공변이라고 한다.
무공변(Invariance) - < T >
S와
T가 서로 관계가 없다.List< S > 와
List<T>는 서로 다른 타입이다.
공변(Covariance) - <? extends T>
상위 타입에서 하위 타입으로 형 변환이 가능한 경우 타입을 공변 타입으로 간주한다.
S가
T의 하위 타입이면S[] 는
T[]의 하위 타입이다.List< S > 는
List<T>의 하위 타입이다.
반공변(Contravariance) - <? super T>
하위 타입에서 상위 타입으로 형 변환이 가능한 경우 타입을 반공변 타입으로 간주한다.
S가
T의 하위 타입이면T[]는 S[] 의 하위 타입이다.(공변의 반대)List<T>는 List< S > 의 하위 타입이다.(공변의 반대)
제네릭 와일드카드
제네릭은
extends와super키워드를 이용해 클래스 상속 관계에서 타입을 하위 타입으로 제한할지, 상위 타입으로 제한할지 타입을 제한할 수 있다.extends는 타입 파라미터에 특정 타입의 하위 타입만을 허용하도록 지정할 때 사용한다.super는 타입 파라미터에 특정 타입의 상위 타입만을 허용하도록 지정할 때 사용한다.
<?>
Unbounded wildcards
제한 없음(모든 타입 가능)
<? extends U>
Upper Bounded Wildcards
상한 경계 와일드카드
- 상위 클래스 제한 (U와 그 자손들만 가능)
- 상한이 U라 상한 경계라고 한다.
<? super U>
Lower Bounded Wildcards
하한 경계 와일드카드
- 하위 클래스 제한 (U와 그 조상들만 가능)
- 하한이 U라 하한 경계라고 한다.
extends / super 사용시기
언제
<? extends T>를 사용하고,<? super T>를 사용해야 할까?PECS
Producer-Extends / Consumer-Super의 약자다.
외부에서 온 데이터를 생산(
Producer)한다면<? extends T>를 사용한다.(하위 타입으로 제한)외부에서 온 데이터를 소비(
Consumer)한다면<? super T>를 사용한다.(상위 타입으로 제한)
참고
Last updated