제네릭이란 무엇인가요?

  • 자바에서 제네릭(Generic) 이란, 클래스 내부에서 사용할 데이터 타입을 외부에서 저장하는 기법을 의미하며, 객체별로 다른 타입의 자료가 저장될 수 있도록 한다.

  • 컴파일 타임에 타입을 체크함으로써 코드의 안전성을 높여주는 기능을 가지고 있다.

img_30.png
  • 제네릭은 다이아몬드 연산자라고 하는 <> 꺾쇠 괄호 키워드를 사용한다.

  • 그리고 이 꺾쇠 괄호 안에 식별자 기호를 지정해 파라미터화할 수 있다.

  • 이것을 마치 메서드가 매개변수를 받아 사용하는 것과 비슷하여 제네릭의 타입 매개변수(parameter) / 타입 변수 라고 부른다.

타입 파라미터 기호 네이밍(암묵적인 규칙)

타입
설명

< T >

타입(Type)

< E >

요소(Element)

< K >

키(Key)

< V >

리턴 값 또는 매핑된 값(Variable)

< N >

숫자(Number)

< S, U, V >

2번째, 3번째, 4번째에 선언된 타입

제네릭을 사용했을 때 이점

  1. 컴파일 타임에 강력한 타입 검사를 통해 예외 방지

    • 제네릭이 나오기 전 자바 1.5 이전에는 Object 를 사용해 제네릭과 비슷하게 구현했다.

    • 이럴 경우 개발자가 일일이 타입 변환을 시도해야 하며, 실수할 가능성이 존재한다.

    • 하지만 제네릭을 사용하면 컴파일 타임에 미리 에러를 잡아주기 때문에 실수를 사전에 방지할 수 있다.

  2. 불필요한 캐스팅 제거

    • 제네릭 없이 Object를 사용하면 매번 다운 캐스팅을 통해 객체를 가져와야 한다.

    • 제네릭을 사용하면 미리 타입을 지정하여 제한하기 때문에 형 변환의 번거로움을 줄일 수 있다.

변성(variance)

List<Object> objectList = new ArrayList<Integer>();

이 코드는 가능할까? IntegerObject의 하위 타입이지만 컴파일 오류가 발생한다.

Object[] objectArr = new Integer[1];

이와 같이 배열에서는 IntegerObject의 하위 타입이 성립이 된다. 이를 공변이라 한다.

하지만 제네릭 같은 경우는 ObjectInteger를 서로 관계가 없다고 보는데 이를 무공변 또는 불공변이라고 한다.

무공변(Invariance) - < T >

  • ST가 서로 관계가 없다.

    • List< S >List<T>는 서로 다른 타입이다.

공변(Covariance) - <? extends T>

  • 상위 타입에서 하위 타입으로 형 변환이 가능한 경우 타입을 공변 타입으로 간주한다.

  • ST의 하위 타입이면

    • S[]T[]의 하위 타입이다.

    • List< S >List<T>의 하위 타입이다.

반공변(Contravariance) - <? super T>

  • 하위 타입에서 상위 타입으로 형 변환이 가능한 경우 타입을 반공변 타입으로 간주한다.

    • ST의 하위 타입이면

      • T[]S[] 의 하위 타입이다.(공변의 반대)

      • List<T>List< S > 의 하위 타입이다.(공변의 반대)

제네릭 와일드카드

  • 제네릭은 extendssuper 키워드를 이용해 클래스 상속 관계에서 타입을 하위 타입으로 제한할지, 상위 타입으로 제한할지 타입을 제한할 수 있다.

  • 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