본문 바로가기

Dev Book Review/Effective Java

[Effective Java] Chapter 5: 제네릭

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
 

[Effective Java] item26. 로타입은 사용하지 말라

1. 용어정리 public class Example{ private T member; } 제네릭 클래스[인터페이스] : 클래스[인터페이스] 선언에 타입 매개변수(type parameter)가 쓰인다. Example.class 제네릭 타입(Generic Type) : 제네..

jyami.tistory.com

 

item27. 비검사 경고를 제거하라

  • 비검사 경고는 중요하지 무시하지 말자.
  • 모든 비검사 경고는 런타임에 ClassCastException을 일을킬 수 있는 잠재적 가능성을 뜻하니 최선을 다해 제거하라
  • 경고를 없앨 방법을 찾지 못하겠다면 그 코드가 타입 안전함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarning("unchecked") 애너테이션으로 경고를 숨겨라
  • 그런다음 경고를 숨기기로 한 근거를 주석으로 남겨라
  • Link : jyami.tistory.com/91
 

[Effective Java] item 27. 비검사 경고를 제거하라

1. 할수있는 한 모든 비검사 경고를 제거하자 제네릭을 사용하기 시작했을 때 볼 수 있는 수많은 컴파일러 경고 비검사 형변환 경고 비검사 메서드 호출 경고 비검사 매개변수화 가변인수 타입 �

jyami.tistory.com

 

item28. 배열보다는 리스트를 사용하라

  • 배열과 제네릭에는 매우 다른 타입 규칙이 적용된다.
  • 배열은 공변이고 실체화되는 반면, 제네릭은 불공변이고 타입정보가 소거된다.
  • 그 결과 배열은 런타임에는 타입 안전하지만 컴파일타임에는 그렇지 않다.
  • 제네릭은 반대로, 컴파일 타임에는 타입 안전하지만 런타임에는 그렇지 않다.
  • 그래서 둘을 섞어쓰기란 쉽지 않으며, 둘을 섞어 쓰다가 컴파일 오류나 경고를 만나면, 가장 먼저 배열을 리스트로 대체하는 방법을 적용하자.
  • 제네릭은 컴파일타임단에서 TypeCasting을 잡아주므로 런타임에 ClassCastingException이 뜨지 않는다.
  • Link : jyami.tistory.com/92
 

[Effective Java] item28. 배열보다는 리스트를 사용하라

1. 배열과 제네릭의 차이 배열 공변 (convariant) - Sub 가 Super 의 하위타입이라면 배열 Sub[] 는 배열 Super[] 의 하위타입이다. (함께 변한다) 배열에서는 실수를 런타임에 타입 오류를 알 수 있다 Object[]

jyami.tistory.com

 

item29. 이왕이면 제네릭 타입으로 만들라

  • 클라언트에서 직접 형변환해야 하는 타입보다 제네릭 타입이 더 안전하고 쓰기 편하다.
  • 새로운 타입을 설계할 때는 형변환 없이도 사용할 수 있도록 하라
  • 그렇게 하려면 제네릭 타입으로 만들어야 할 경우가 많다
  • 기존 타입중 제네릭이었어야 하는게 있다면 제네릭 타입으로 변경하자.
  • 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해준다. (raw 타입의 등장 이유)
  • Link : jyami.tistory.com/93
 

[Effective Java] item29. 이왕이면 제네릭 타입으로 만들라

1. 제네릭클래스로 만드는 방법 a. 클래스 선언에 타입매개변수를 추가한다. 보통 E를 많이 사용한다. 제네릭 필드를 쓴다는 것을 명시하는 것이다. b. 실체화 불가 타입으로는 배열을 만들 수 없�

jyami.tistory.com

 

item30. 이왕이면 제네릭 메서드로 만들라

  • 제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다.
  • 타입과 마찬가지로, 메서드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메서드가 되어야한다.
  • 역시 타입과 마찬가지로 형변환을 해줘야하는 기존 메서드는 제네릭하게 만들자
  • 기존 클라이언트는 그대로 둔 채 새로운 사용자의 삶을 훨씬 편하게 만들어줄 것이다 (raw 타입의 등장이유)
  • Link : jyami.tistory.com/94
 

[Effective Java] item30. 이왕이면 제네릭 메서드로 만들라

1. 제네릭 메서드 만들기 메서드도 제네릭으로 만들 수 있다. ex ) Collections의 '알고리즘' 메서드 메서드 선언에서 원소타입을 타입 매개변수로 지정한다. 메서드 안에서 이 타입 매개변수를 사용�

jyami.tistory.com

 

Item31. 한정적 와일드 카드를 사용해 API 유연성을 높여라

  • 조금 복잡해도 와일드 카드 타입을 적용하면 API가 훨씬 유연해진다.
  • 널리쓰일 라이브러리를 작성한다면 반드시 와일드카드 타입을 적절히 사용해주자.
  • PECS 공식을 기억하자
  • producer는 extends를 consumer는 super를 사용한다.
  • Comparable과 Comparator는 모두 소비자이다.
  • Link : jyami.tistory.com/95
 

[Effective Java] item31. 한정적 와일드 카드를 사용해 API 유연성을 높여라

1. 매개변수화 타입의 불공변 매개변수화 타입은 불공변이다(invariant) : 서로 다른 타입 Type1 , Type2 가 있을 때 List 은 List 의 하위타입도 아니고 상위타입도 아니다. (리스코프 치환 원칙

jyami.tistory.com

 

item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라

  • 가변인수와 제네릭은 궁합이 좋지 않다.
  • 가변인수 기능은 배열을 노출하여 추상화가 완벽하지 못하고, 배열과 제네릭의 타입 규칙이 서로 다르기 때문이다.
  • 제네릭 varargs 매개변수는 타입 안전하지는 않지만, 허용된다.
  • 메서드에 제네릭(혹은 매개변수화된) varargs 매개변수를 사용하고자 한다면, 먼저 그 메서드가 타입 안전한지 확인한 다음 @SafeVarargs 애너테이션을 달아 사용하는데 불편함이 없게끔 하자.
  • Link : jyami.tistory.com/96
 

[Effective Java] item32. 제네릭과 가변인수를 함께 쓸 때는 신중하라

1. 가변인수와 제네릭을 함께 사용할 때의 헛점 가변인수 메서드를 호출하면 가변인수를 담기위한 배열이 자동으로 하나 만들어진다. 내부로 감춰야했을 배열을 클라이언트에 노출해서 문제가

jyami.tistory.com

 

item33. 타입 안전 이종 컨테이너를 고려하라

  • 컬렉션 API로 대표되는 일반적인 제네릭 형태에서는 한 컨테이너가 다룰 수 있는 타입 매개변수의 수가 고정되어 있다.
  • 하지만 컨테이너 자체가 아닌 키를 타입 매개변수로 바꾸면 이런 제약이 없는 타입 안전 이종 컨테이너를 만들 수 있다.
  • 타입 안전 이종 컨테이너는 Class를 키로 쓰며, 이런식으로 쓰이는 Class 객체를 타입 토큰이라 한다.
  • 또한, 직접 구현한 키 타입도 쓸 수 있다.
  • 데이터베이스 행(컨테이너)을 표현한 DatabaseRow 타입에는 제네릭타입인 Column<T>를 키로 쓸 수 있다.
  • Link : jyami.tistory.com/97
 

[Effective Java] item33. 타입 안전 이종 컨테이너를 고려하라

1. 타입 안전 이종 컨테이너 패턴 매개변수화 되는 대상은 원소가 아닌 컨테이너 자신이다 Set 가 있을 때 매개변수화 되는 것은 Integer 가 아니라 List 이다. 하나의 컨테이너에서 매��

jyami.tistory.com