지네릭스(Generics)란?
지네릭스란 컴파일시 타입을 체크해 주는 기능이다. (JDK 1.5 이상부터 가능)
ArrayList<Coffee> coffeeList = new ArrayList<Coffee>();
coffeeList.add(new Coffee()); // 컴파일 성공
coffeeList.add(new Cake()); // 컴파일 에러 (JDK 1.5 이전에는 컴파일 성공됐음)
지네릭스 도입 이후(JDK 1.5 이후)부터는 ArrayList list = new ArrayList(); 라고 쓰기보다는
ArrayList<Object> list = new ArrayList<Object>(); 라고 쓰는 것이 더 좋다.
지네릭스를 사용하지 않아도 에러가 나는 것은 아니지만, 지네릭스 도입 이후 버전에서는 전자와 같이 쓰는 것은 좋은 코드가 아니다.
(*클래스 이름 옆에 <E> 표시가 붙어 있는 것이 지네릭스 클래스이다.)
(*<E>는 'E의 Box' 또는 'E Box'라고 읽는다.)
지네릭스를 왜 사용하는지
앞서 말했듯이 지네릭스는 타입을 체크해주는 기능으로써, 지정한 타입이 아닌 경우 에러가 난다.
지네릭스를 사용함으로써 얻을 수 있는 장점
- 타입의 안정성을 제공할 수 있다.
- 에러를 조기 발견할 수 있다. (런타임에러를 컴파일에러로 변경)
- 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해진다.
타입 변수 (타입 매개변수)
타입 변수 또는 타입 매개변수는 클래스를 작성할 때 Object타입 대신 선언하는 변수이다.
예전에는 Object라는 일반 클래스를 사용했었는데, 지네릭스가 도입된 이후에는 타입 변수(E)라는 지네릭 클래스를 이용하는 것으로 바뀌었다.
타입 변수는 배열 요소를 의미하는 Element의 앞글자인 E 또는 Type의 앞글자인 T를 많이 쓴다. (E 또는 T를 타입 문자라고 부른다)
그렇다면 타입 변수는 어떻게 사용하는 것일까?
클래스를 작성할 때 타입 변수로 지정해두었으면, 이후 객체를 생성할 때 타입 변수 대신 실제 사용할 타입을 지정한다.
클래스를 작성할 때 타입 변수로 지정해두었던 부분에는 실제 타입이 대입되게 된다.
타입 변수에 실제 타입이 대입되므로 형변환을 생략할 수 있게 되면서 코드가 간결해진다.
HashMap<K, V>
타입 변수가 여러 개가 필요한 경우 HashMap을 이용하면 된다.
<K, V>는 각각 Key와 Value의 앞 글자를 딴 타입 변수이다.
사용법은 아래와 같다.
HashMap<String, Coffee> map = new HashMap<String, Coffee>();
map.put("카페라떼", new Coffee());
extends 지네릭스
지네릭스 타입에 extends로 상속받을 타입을 정할 수 있다.
제한된 지네릭 클래스라고도 부르며, 융통적이면서도 엄격한 타입 제한이 가능하다.
class Latte<T extends Coffee> { }
Coffee 클래스를 상속받는 지네릭 타입이므로 아래와 같이 Juice 타입을 받을 수는 없다.
Latte<Juice> juice = new Latte<Juice>(); // Error
지네릭스의 제약
지네릭스에는 제약이 몇 개 있다.
- static 멤버에 타입 변수 사용 불가
- 배열 생성할 때 타입 변수 사용 불가 (타입 변수로 배열 선언은 가능) (즉, new 연산자 뒤에는 타입 변수 T 사용 불가)
제네릭 와일드카드: <?>, <? super T>, <? extends T>
타입 변수에 ?를 넣을 수도 있다.
제네릭 와일드카드라고 부르며 각각의 의미는 아래와 같다.
<? extends T> | 상한 제한, T와 그 자손들만 가능 |
<? super T> | 하한 제한, T와 그 조상들만 가능 |
<?> | 제한 없음, 모든 타입이 가능 (<? extends Object>와 동일) |
(출처: 유튜브 남궁성의 정석코딩)
'Java' 카테고리의 다른 글
[Java] File 클래스, 대표 함수들 간단한 정리 (0) | 2021.12.13 |
---|---|
[Java] 자바의 예외 종류 (0) | 2021.11.12 |
[Java] 내부 클래스의 접근성 (0) | 2021.11.10 |
[IntelliJ] 인텔리제이 프로젝트 깃허브에 올리기 (0) | 2021.10.05 |
[Java] spring과 spring boot의 차이는 무엇일까? (0) | 2021.09.07 |