forDevLife
[자바의정석] Chap 12. 지네릭스 본문
1.1 ~ 1.5) 지네릭스 주요 정리
- 반드시 타입을 지정하여 지네릭스 경고가 나오지 않도록 하자.(호환성을 유지하기 위해 지네릭스 사용안한 코드를 허용하는 것일 뿐)
- static 멤버에는 타입변수 사용 불가하다. 모든 객체에 동일하게 동작해야 하므로
- 지네릭 타입의 배열 생성 허용하지 않는다.(참조변수 선언은 가능)
-. T[] itemArr; // ok, T타입의 배열을 위한 참조변수
-. T[] tmpArr = new T[itemArr.length]; // error, 지네릭 배열 생성 불가 - 컴파일 시점에 T가 뭔지 모르므로 에러 발생
-. 같은 이유로, instanceof 연산자 / new 연산자에서도 사용 불가
-. 꼭 사용해야 하는 경우, 'Reflection API'의 newInstnace()와 같이 동적으로 객체를 생성, 또는 Object 배열에서 복사 후 T[]로 형 변환
- <? extends T> : 와일드 카드의 상한 제한, T와 그 자손들만 사용 가능
- <? super T> : 와일드 카드의 하한 제한, T와 그 조상들만 가능
- <?> : 제한 없음, 모든 타입이 가능. <? extends Object>와 동일 기능
- static <T> void sort(List<T> list, Comparator<? super T> c) 와 같이 Collections.sort()가 정의되어있다.
여기에서 정렬하고자 하는 List를 입력하면, 예를 들어 fruit를 상속받는 apple을 타입 변수로 지정한다고 가정하자.
List<apple> list, Comparator<? super apple> c 와 같이 정리가 되는데, 이때 Comparator로 올 수 있는 항목은 다음과 같다.
1. Comparator<apple>
2. Comparator<fruit>
3. Comparator<Object>
따라서, 2번 이상의 Comparator를, fruit를 상속받는 class들 끼리 공용으로 사용 가능하다.
1.6) 지네릭 메서드
- 메서드 선언부에 지네릭 타입이 선언된 메서드. 선언 위치는 반환 타입 바로 앞이다.
ex) static <T> void sort(~)
- 지네릭 메서드는 일반 클래스에서도 정의될 수 있다.
- 지네릭 클래스 내에 지네릭 메서드가 정의되었을 때, 여기서 정의된 두 타입변수는 전혀 별개의 것이다. 즉 지네릭 메서드에 정의된 타입변수는 그 안에서마 사용되는 지역 변수라고 생각하면 된다.
- 매개변수의 타입이 복잡할 때, 유용하게 사용된다.
1.7) 지네릭 타입의 형변환
- 지네릭 & non-지네릭간의 형변환은 항상 가능(경고는 발생)
- 대입된 타입이 다른 지네릭 타입일 경우에는 형변환 불가.
-. Box<Object> objBox = new Box<String>(); // 타입이 달라 형변환 불가
-. Box<? extends Object> objBox = new Box<String>(); // 이 경우에는 형변환 가능해진다.
-. 위의 항을 좌 우 변경해도 가능하지만, 경고는 발생한다. 즉,
Box<? extends Object> objBox = null;
Box<String> stringBox = (Box<String>)objBox; // 가능하지만 경고 발생.
- 정리하자면, 1) 와일드카드가 포함된 지네릭 타입으로도 형변환 가능, 2) 그 반대(but warning)로도 형변환이 가능하다.
Optional<? extends Object> wopt = new Optional<Object>(); -> 1) 와일드카드가 포함된 지네릭 타입으로 변경 가능
Optional<Object> oopt = new Optional<Object>();
Optional<String> sopt = (Optional<String>)wopt; -> 2) 그 반대, 즉 와일드카드가 포함된 걸 다른 타입으로 변경 가능
Optional<String> sopt = (Optional<String>)oopt; // 이건 에러. oopt가 와일드카드가 포함된 지네릭이 아니므로.
- 마지막으로, 와일드카드가 사용된 지네릭 타입끼리도 형변환이 가능(마찬가지로 경고)
1.8) 지네릭 타입의 제거
- 컴파일러는 지네릭 타입 이용하여 소스파일 체크하고, 필요한 곳에 형변환을 넣어준다.
- 그 다음 지네릭을 제거한다. 즉 컴파일된 파일(*.class)에는 지네릭 타입에 대한 정보가 없다. 하위 호환성을 위해.
'Java' 카테고리의 다른 글
[자바의정석] Chap 13. 쓰레드 (0) | 2021.03.16 |
---|---|
[자바의정석] Chap 12. 열거형, 애너테이션 (0) | 2021.03.10 |
[자바의정석] Chap 11. 컬렉션 프레임워크(Arrays / comparator / comparable) (0) | 2021.02.08 |
[자바의정석] Chap 11. 컬렉션 프레임워크(스택, 큐) (0) | 2021.01.29 |
[자바의정석] Chap 7. 객체지향 프로그래밍 (내부 클래스) (0) | 2021.01.06 |