제네릭
-
로 타은은 사용하지 말라
-
로 타입(raw type)을 사용하면 런타임에 예외가 일어날 수 있으니 사용하면 안된다. 로 타입은 제네릭이 도입되기 이전 코드와의 호환성을 위해 제공될 뿐이다. 빠르게 훑어보자면, Set<Object> 는 어떤 타입의 객체도 저장할 수 있는 매개변수화 타입이고, Set<?>는 모종의 타입 객체만 저장할 수 있는 와일드 카드 타입이다. 그리고 이들의 로 타입인 Set 은 제네릭 타입 시스템에 속하지 않는다. Set<Object> 와 Set<?> 안정하지만, 로 타입인 Set은 안전하지 않다.
-
-
비검사 경고를 제거하라.
-
비검사 경고는 중요하니 무시하지 말자. 모든 비검사 경고는 런타임에 ClassCastException 을 일으킬 수 있는 잠재적 기능성을 뜻하니 최선을 다해 제거하라. 경고를 없앨 방법을 찾지 못하겠다면, 그 코드가 안전함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarnings("unchecked") 애너테이션으로 경고를 숨겨라. 그런 다음 경고를 숨기기로 한 근거를 주석으로 남겨라
-
-
배열보다는 리스트를 사용하라
-
배열과 제네릭에는 매우 다른 타입 규칙이 적용된다. 배열은 공변이고 실체화되는 반면, 제네릭은 불공변이고, 타입 정보가 소거된다. 그 결과 배열은 런타임에는 타입 안전하지만 컴파일타임에는 그렇지 않다. 제네릭은 반대다.그래서 둘을 섞어 쓰기란 쉽지 않다. 둘을 섞어 쓰다가 컴파일 오류나 경고를 만나면, 가장 먼저 배열을 리스트로 대처하는 방법을 적용해 보자.
-
-
이왕이면 제네릭 타입으로 만들라
-
클라이언트에서 직접 형변환해야 하는 타입보다 제네릭 타입이 더 안전하고 쓰기 편하다. 그러니 새로운 타입을 설계할 때는 형변환 없이도 사용할 수 있도록 하라. 그렇게 하려면 제네릭 타입으로 만들어야 할 경우가 많다. 기존 타입 중 제네릭이었어야 하는 게 있다면 제네릭 타입으로 변경하자. 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 휠씬 편하게 해주는 길이다.
-
-
이와이면 제네릭 메서드로 만들라
-
제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다. 타입과 마찬가지로, 메서드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메서드가 되어야 한다. 역시 타입과 마찬가지로, 형변환을 해줘야 하는 기존 메서드는 제네릭하게 만들자. 기존 클라이언트는 그대로 둔채 새로운 사용자의 삶을 휠씬 편하게 만들어줄 것이다.
-
-
한정적 와일드 카드를 사용해 API 유연성을 높이라
-
조금 복잡하더라고 와이드카드 타입을 적용하면 API가 휠씬 유연해 진다. 그러니 널리 쓰일 라이브러리를 작성한다면 반드시 와이드카드 타입을 적절히 사용해줘야 한다. PECS공식을 기억하자. 즉, 생산자(producer)는 extends를 소비자(consumer)는 super를 사용한다. Comparable 과 Comparator는 모두 소비자라는 사실도 잊지 말자.
-
-
제네릭과 가변인수를 함께 쓸 때는 신중하라
-
가변인수와 제네릭은 궁합이 좋지 않다. 가변인수 기능은 배열을 노출하여 추상화가 완벽하지 못하고, 배열과 제네릭의 타입 규칙이 서로 다르기 때문이다. 제네릭 varargs 매개변수는 타입 안정하지는 않지만, 허용된다. 메서드에 제네릭(혹은 매개변수화된) varargs 매개변수를 사용하고자 한다면, 먼저 그 메서드가 타입 안전한지 확인한 다음 @SafeVarargs 애너테이션을 달아 사용하는 데 불편함이 없게끔 하자.
-
-
타입 안정 이종 컨테이너를 고려하라.
-
컬렉션 API로 대표되는 일반적인 제네릭 형태에서는 한 컨테이너가 다룰 수 있는 타입 매개변수의 수가 고정되어 있다. 하지만 컨테이너 자체가 아닌 키를 타입 매개변수로 바꾸면 이런 제약이 없는 타입 안정 이종 컨테이너를 만들 수 있다. 타입 안정 이종 컨테이너는 Class를 키로 쓰며, 이런 식으로 쓰이는 Class 객체를 타입 토큰이라 한다. 또한, 직접 구현한 키 타입도 쓸 수 있다. 예컨대 데이터베이스의 행(컨테이너)을 표현한 DatabaseRow 타입에는 제네릭 타입인 Column<T>를 키로 사용할 수 있다.
-
참조서적 및 페이지 :
이펙티브 자바 Effective Java 3/E (http://www.yes24.com/Product/Goods/65551284)
'백엔드 > Java' 카테고리의 다른 글
Effective Java 맛보기 8탄 (0) | 2019.09.21 |
---|---|
Effective Java 맛보기 7탄 (0) | 2019.09.20 |
Effective Java 맛보기 6탄 (0) | 2019.09.20 |
Effective Java 맛보기 5탄 (0) | 2019.09.17 |
Effective Java 맛보기 3탄 (0) | 2019.09.15 |
Effective Java 맛보기 2탄 (0) | 2019.09.15 |
Effective Java 맛보기 1탄 (0) | 2019.09.14 |
Spring Data Redis - Jedis vs Lettuce (0) | 2019.08.18 |
댓글