[이펙티브자바] 6장 열거 타입과 애너테이션(item34-41) 정리

예니·2022년 9월 29일
0

이펙티브자바

목록 보기
5/11
post-thumbnail

아이템 34. int 상수 대신 열거 타입을 사용하라

  • 정수 열거 패턴 단점 많다. 열거 타입을 쓰자!
  • 열거 타입은 완전한 형태의 클래스. 상수 하나당 자신의 인스턴스를 하나씩 생성해 public static final 필드로 공개한다.
  • 외부에서 접근 가능한 생성자를 제공하지 않는다.
  • 열거 타입에는 임의의 메소드나 필드를 추가할 수 있고 임의의 인터페이스를 구현하게 할 수도 있다.
  • 열거 타입은 불변이니까 모든 필드는 final 이어야 함!
  • 필요한 원소를 컴파일타임에 다 알 수 있는 상수 집합이라면 항상 열거 타입 쓰자!

아이템 35. ordinal 메서드 대신 인스턴스 필드를 사용하라

  • ordinal 메서드 사용하지 말고 인스턴스 필드에 저장하자!
  • ordinal 메서드는 enumSet, enumMap 같은 열거 타입 기반 범용 자료구조에 쓸 목적으로 설계되었다. 그 외 용도라면 ordinal 메서드를 사용하지 말자

아이템 36. 비트 필드 대신 EnumSet을 사용하라

  • 비트별 OR를 사용해 여러 상수를 하나의 집합으로 모은 것을 비트 필드라 한다.
  • 비트 필드 단점
    1. 정수 열거 상수의 단점을 그대로 가짐
    2. 비트 필드값 그대로 노출되면 해석 어려움
    3. 최대 몇 비트가 필요한지 처음부터 예상하여 적절한 타입을 선택해야함
  • java.util.EnumSet을 사용하자. 장점
    1. Set 인터페이스를 구현하여 어떤 Set 구현체와도 사용 가능, typeSafe
    2. 내부가 비트 벡터로 구현되어 있어, 비트 필드에 비견되는 성능
  • EnumSet은 불변 객체 못 만드는데, 만들고 싶으면 guava꺼 사용하기
    Collections.unmodifiableSet() 으로 감싸서 사용하면 불변 가능

아이템 37. ordinal 인덱싱 대신 EnumMap을 사용하라

  • Ordinal 쓰지말자. Ordinal 인덱싱 대신 EnumMap(enum 을 key 로 가짐)을 사용하라
  • EnumMap은 내부에서 배열을 사용하기 때문에 ordinal 쓴 배열의 성능과 견줄 수 있다.

아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

  • enum도 인터페이스를 구현할 수 있다.
  • enum끼리는 구현을 상속할 수 없다.
    https://www.baeldung.com/java-extending-enums
    1. enum 은 java.lang.Enum 이라는 abstract class 의 하위클래스이다. enum A / enum B extends A 를 하면 B 는 java.lang.Enum 도 상속하고, A 도 상속하게 된다. → 다중상속은 자바에서 지원X
    2. 컴파일 할 때 enum 을 final class 로 컴파일한다 (final class 는 extend 불가능)

아이템 39. 명명 패턴보다 에너테이션을 사용하라

  • 명명 패턴이란 변수나 함수의 이름을 일관된 방식으로 작성하는 패턴을 말한다. 문제점이 많다. 사용자가 특히 주의해야함
  • 애너테이션을 쓰면 문제점이 해결된다.
  • 마커 어노테이션
    아무 매개변수 없이 대상에 단순 마킹 용도
  • 메타 어노테이션
    @Retention : 어디까지 살아있을지 (런타임, 클래스, 소스)
    @Target : 어노테이션이 붙을 대상 알려줌 (METHOD, TYPE, FIELD ..)
  • @Repeatable
    같은 어노테이션 중복 정의 가능
    이 어노테이션들의 묶음을 관리하는 컨테이너 어노테이션이 있어야함
    이때 하위, 컨테이너 어노테이션 모두에 Retention, Target 잘 붙여주자

아이템 40. @Override 애너테이션을 일관되게 사용하라

  • @Override 애너테이션을 굳이 안붙여도 되는 상황이 있지만, 명확한 기준을 세우고 일관되게 사용하자.
  • 항상 붙이거나 or 불필요한 곳엔 아예 안붙이거나

아이템 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라

  • 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 instanceof 등으로 구분할 수 있다. (컴파일타임에)
    마커 애너테이션을 사용했다면 clazz.isAnnotationPresent(Markable1.class) 등으로 인스턴스를 구분할 수는 있지만, 런타임에야 오류를 발견할 수 있다.
  • 마커 인터페이스는 대상을 더 정밀하게 지정할 수 있다.
    @TargetElementType.TYPE으로 지정해도 클래스, 인터페이스, enum, 애너테이션에 달 수 있다.
    마커 인터페이스는 마킹하고 싶은 클래스에만 달 수 있다. → 하위 타입임이 보장됨
  • 마킹이 된 객체를 매개변수로 받는 메서드를 작성할 일이 있다면 마커 인터페이스를 사용하자.

0개의 댓글