728x90
용어정리
한글 | 영문 | 예 |
---|---|---|
매개변수화 타입 | parameterized type | List<String> |
실제 타입 매개변수 | actual type parameter | String |
제네릭 타입 | generic type | List<E> |
정규 타입 매개변수 | formal type parameter | E |
비한정적 와일드카드 타입 | unbounded wildcard type | List<?> |
로 타입 | raw type | List |
한정적 타입 매개변수 | bounded type parameter | <E extends Number> |
재귀적 타입 한정 | recursive type bound | <T extends Comparable<T>> |
한정적 와일드카드 타입 | Bounded wildcard type | <? extends Number> |
제네릭 메서드 | generic method | static <E> List<E> asList(E[] a) |
타입 토큰 | type token | String.class |
item26. 로 타입은 사용하지 말라
- 로타입을 사용하면 런타임에 예외가 일어날 수 있으니 사용하면 안 된다.
- 로 타입은 제네릭이 도입되기 이전 코드와의 호환성을 위해 제공될 뿐이다.
- 매개변수화 타입 : 어떤 타입의 객체도 저장할 수 있다.
Set<Object>
- 와일드카드 타입 : 모종의 타입 객체만 저장할 수 있다.
Set<?>
- 로타입 : 제네릭 타입 시스템에 속하지 않는다.
Set
Set<Object>
,Set<?>
는. 안전하지만, 로타입인Set
은 안전하지 않다.- Link : jyami.tistory.com/90
item27. 비검사 경고를 제거하라
- 비검사 경고는 중요하지 무시하지 말자.
- 모든 비검사 경고는 런타임에 ClassCastException을 일을킬 수 있는 잠재적 가능성을 뜻하니 최선을 다해 제거하라
- 경고를 없앨 방법을 찾지 못하겠다면 그 코드가 타입 안전함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarning("unchecked") 애너테이션으로 경고를 숨겨라
- 그런다음 경고를 숨기기로 한 근거를 주석으로 남겨라
- Link : jyami.tistory.com/91
item28. 배열보다는 리스트를 사용하라
- 배열과 제네릭에는 매우 다른 타입 규칙이 적용된다.
- 배열은 공변이고 실체화되는 반면, 제네릭은 불공변이고 타입정보가 소거된다.
- 그 결과 배열은 런타임에는 타입 안전하지만 컴파일타임에는 그렇지 않다.
- 제네릭은 반대로, 컴파일 타임에는 타입 안전하지만 런타임에는 그렇지 않다.
- 그래서 둘을 섞어쓰기란 쉽지 않으며, 둘을 섞어 쓰다가 컴파일 오류나 경고를 만나면, 가장 먼저 배열을 리스트로 대체하는 방법을 적용하자.
- 제네릭은 컴파일타임단에서 TypeCasting을 잡아주므로 런타임에 ClassCastingException이 뜨지 않는다.
- Link : jyami.tistory.com/92
item29. 이왕이면 제네릭 타입으로 만들라
- 클라언트에서 직접 형변환해야 하는 타입보다 제네릭 타입이 더 안전하고 쓰기 편하다.
- 새로운 타입을 설계할 때는 형변환 없이도 사용할 수 있도록 하라
- 그렇게 하려면 제네릭 타입으로 만들어야 할 경우가 많다
- 기존 타입중 제네릭이었어야 하는게 있다면 제네릭 타입으로 변경하자.
- 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해준다. (raw 타입의 등장 이유)
- Link : jyami.tistory.com/93
item30. 이왕이면 제네릭 메서드로 만들라
- 제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다.
- 타입과 마찬가지로, 메서드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메서드가 되어야한다.
- 역시 타입과 마찬가지로 형변환을 해줘야하는 기존 메서드는 제네릭하게 만들자
- 기존 클라이언트는 그대로 둔 채 새로운 사용자의 삶을 훨씬 편하게 만들어줄 것이다 (raw 타입의 등장이유)
- Link : jyami.tistory.com/94
Item31. 한정적 와일드 카드를 사용해 API 유연성을 높여라
- 조금 복잡해도 와일드 카드 타입을 적용하면 API가 훨씬 유연해진다.
- 널리쓰일 라이브러리를 작성한다면 반드시 와일드카드 타입을 적절히 사용해주자.
- PECS 공식을 기억하자
- producer는 extends를 consumer는 super를 사용한다.
- Comparable과 Comparator는 모두 소비자이다.
- Link : jyami.tistory.com/95
item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라
- 가변인수와 제네릭은 궁합이 좋지 않다.
- 가변인수 기능은 배열을 노출하여 추상화가 완벽하지 못하고, 배열과 제네릭의 타입 규칙이 서로 다르기 때문이다.
- 제네릭 varargs 매개변수는 타입 안전하지는 않지만, 허용된다.
- 메서드에 제네릭(혹은 매개변수화된) varargs 매개변수를 사용하고자 한다면, 먼저 그 메서드가 타입 안전한지 확인한 다음 @SafeVarargs 애너테이션을 달아 사용하는데 불편함이 없게끔 하자.
- Link : jyami.tistory.com/96
item33. 타입 안전 이종 컨테이너를 고려하라
- 컬렉션 API로 대표되는 일반적인 제네릭 형태에서는 한 컨테이너가 다룰 수 있는 타입 매개변수의 수가 고정되어 있다.
- 하지만 컨테이너 자체가 아닌 키를 타입 매개변수로 바꾸면 이런 제약이 없는 타입 안전 이종 컨테이너를 만들 수 있다.
- 타입 안전 이종 컨테이너는 Class를 키로 쓰며, 이런식으로 쓰이는 Class 객체를 타입 토큰이라 한다.
- 또한, 직접 구현한 키 타입도 쓸 수 있다.
- 데이터베이스 행(컨테이너)을 표현한
DatabaseRow
타입에는 제네릭타입인Column<T>
를 키로 쓸 수 있다. - Link : jyami.tistory.com/97
'Dev Book Review > Effective Java' 카테고리의 다른 글
[Effective Java] item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2020.06.27 |
---|---|
[Effective Java] item 34. int 상수 대신 열거 타입을 사용하라 (2) | 2020.06.27 |
[Effective Java] item33. 타입 안전 이종 컨테이너를 고려하라 (0) | 2020.05.19 |
[Effective Java] item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 (0) | 2020.05.19 |
[Effective Java] item31. 한정적 와일드 카드를 사용해 API 유연성을 높여라 (0) | 2020.05.19 |