Effective Java 3/E - (6) 열거타입과 어노테이션

신복호·2020년 12월 6일
0

Effactive JAVA 3/E

목록 보기
6/12
post-thumbnail

6장 열거타입과 어노테이션

JAVA에는 특수한 목적의 참조타입이 두가지 있다.

  • 열거 타입 (enum)

    한정된 값만을 같는 데이터 타입

    public Enum Day(){
       MONDAY;
       TUESDAY;
       WEDNESDAY;
       THURSDAY;
       FRIDAY;
       SATURDAY;
       SUNDAY;
    }
  • 어노테이션 (annotation)

    자바 애너테이션(Java Annotation)은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여서 사용한다. JDK 1.5 버전 이상에서 사용 가능하다. 자바 애너테이션은 클래스 파일에 임베디드되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.

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

  • 열거타입이 정수 상수보다 좋은점은 더 읽기 쉽고 안전하고 강력하다.
  • 대다수 열거 타입이 명시적 생성자나 메소드 없이 쓰이지만, 각 상수를 특정 데이터와 연결 짓거나 상수마다 다르게 동작할때는 필요하다.
  • 그물게는 하나의 메소드가 상수별로 다르게 동작해야 할때도 있는데 이때는 switch문 대신 상수별 메소드 구현을 사용하는 것이 좋다.
  • 열거타입 상수 일부가 같은 동작을 공유한다면 전략 열거 타입 패턴을 사용하자.

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

ordinal 메소드 : 해당 상수가 열거타입에서 몇번째 인지를 반환해주는 메소드

  • 상수의 선언을 바꾸는 순간 오작동할 가능성이 있으며, 이미 사용중인 정수와 같은 상수는 추가 할수 없다.

    public Enum Day(){
       MONDAY;
       TUESDAY;
       WEDNESDAY;
       THURSDAY;
       FRIDAY;
       SATURDAY;
       SUNDAY;
       
       public int numberOfDays() {return ordinal() + 1}
    }
  • 열거 타입 상수에 연결된 값들은 ordinal 메소드로 얻지말고, 인스턴스 필드에 저장해서 사용하자

    public Enum Day(){
       MONDAY(1);
       TUESDAY(2);
       WEDNESDAY(3);
       THURSDAY(4);
       FRIDAY(5);
       SATURDAY(6);
       SUNDAY(7);
       
       private final int int numberOfDay;
       Ensemble(int size) { this.numberOfDay = size; }
       public int numberOfDay() { return numberOfDay; }
    }

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

  • 열거할 수 있는 타입을 한데 모아 집합 형태로 사용한다고 해도 비트 필드를 사용할 이유는 없다.
  • EnumSet 클래스가 비트 필드 수준의 명료함과 서능을 제공하고 열거타입의 장점까지 선사한다.
  • EnumSet의 유일한 단점은 (~ JAVA 11) 불변의 EnumSet을 만들수 없다.
  • 그때까지 명확성과 성능이 조금 희생되지만 Collections.unmodifiableSet으로 EnumSet을 감싸 사용할수 없다.

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

  • 배열의 인덱스를 얻기 위해 ordinal을 쓰는 것은 일반적으로 좋지 않으나, 대신 EnumMap을 사용하자
  • 다차원 관계는 EnumMap<... EnumMap<...>>으로 표현하라
  • 어플리케이션 프로그래머는 Enum.ordinal을 (웬만해서는) 사용하지 말아야 한다.

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

  • 열거타입 자체는 확장할수 없으나, 인터페이스와 인터페이스를 구현하는 기본 열거 타입을 함께 사용해 같은 효과를 나타 낼수 있다.
  • 이렇게 하게 되면 클라이언트는 이 인터페이스를 구현해 자신만의 열거 타입(또는 다른 타입)을 만들 수 있다.
  • API가 인터페이스 기반으로 작성되었다면 기본 열거 타입과 인스턴스가 쓰이는 모든 곳은 새로 확장한 열거 타입의 인스턴스로 대체해 사용할수 있다.

아이템 39. 명명 패턴 보다 어노테이션을 이용하자

  • 명명패턴의 단점
    • 오타가 실행에 영향을 주었다.
    • 특정 예외가 발생하는지에 대해서 검사를 하고 싶을때도 매개변수를 전달할수 있는 방법이 없어 불편했다.
  • JUnit4 부터 어노테이션을 도입하였다.

아이템 40. @Override 어노테이션을 일관대게 사용하자

  • 상위 클래스의 메소드를 재정의하려는 오든 메소드에 @Override 어노테이션을 달자 (예외 - 구체 클래스에서 상위 클래스의 추상 메소드를 재정의 할때)

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

마커 어노테이션이 등장하면서 마커 인터페이스는 구식이 되었다라는 이야기를 들은적이 있을것이다.

마커 인터페이스 장점

  • 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸수 있으나, 마커 어노테이션은 어엿한 타입이기 때문에 그렇지 못하다.

  • 적용 대상을 더 정밀하게 지정할수 있다.

마커 어노테이션의 장점

  • 반대로 마커 어노테이션이 마커 인터페이스보다 나은 점으로는 거대한 어노테이션 시스템의 지원을 받을수 있다.

    -> 마커 인터페이스와 마커 어노테이션은 각자의 쓰임이 있다.

정리

  • 새로 추가하는 메소드 없이 단지 타입의 정의가 목적이라면 마커 인터페이스를 사용하는 것이 좋다. 클래스나 인터페이스 외의 프로그램 요소에 마킹 해야 하거나, 어노테이션을 적극 활용하는 프레임워크의 일부로 그 마커를 편입시키고자 한다면 마커 어노테이션이 좋다.

적용 대상이 ElementType.TYPE 인 마커 어노테이션을 작성하고 있다면, 잠시 여유를 가지고 마커 어노테이션 으로 구현하는게 옳은지, 혹은 마커 인터페이스가 낫지는 않을지 곰곰히 생각을 해봐야 한다.

profile
한참 열정이 가득한 백엔드 개발자입니다.

0개의 댓글