Post

이펙티브 자바 06

이펙티브 자바 06

자바를 잘 다루기 위해 이펙티브 자바를 읽고 정리한 내용입니다. 😊

6장. 열거 타입과 애너테이션

이 장에서는 자바에서 int 상수나 명명 규칙보다 더 안전하고 강력한 대안인 열거 타입(enum)과, 코드에 메타데이터를 부착할 수 있는 애너테이션(annotation)에 대해 다룬다.


열거 타입(Enum)이란?

enum은 서로 관련된 상수들을 하나의 타입으로 묶어 표현할 수 있게 해주는 특수한 클래스다.
단순한 int 상수보다 타입 안전성, 코드 명확성, 기능 확장성이 뛰어나다.

1
2
3
public enum OrderStatus {
    PENDING, SHIPPED, DELIVERED, CANCELLED
}

애너테이션(Annodation)이란?

애너테이션은 코드에 의미 있는 메타데이터를 추가할 수 있게 해준다.
컴파일러, 프레임워크, IDE 등이 애너테이션을 활용하여 자동 검사, 코드 생략, 문서화 등을 수행할 수 있다.

1
2
3
4
@Override
public String toString() {
    return "Hello";
}

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

  • int 상수는 타입이 섞일 수 있어 안전하지 않다.
  • enum을 사용하면 컴파일 타임에 오류를 잡을 수 있다.
  • 상태값이나 역할(Role)을 다룰 때 enum을 도입하면 조건문도 훨씬 명확해진다.
1
2
3
public enum Direction {
    NORTH, SOUTH, EAST, WEST
}

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

  • ordinal()은 선언 순서에 의존해 깨지기 쉽다.
  • 명시적인 필드를 사용해서 의미 있는 값을 부여하자.
  • DB 저장 시 ordinal()을 쓰면 enum 순서가 바뀌는 순간 망한다. name() 또는 직접 필드를 매핑하자.
1
2
3
4
5
6
7
public enum Grade {
    BASIC(1), VIP(2);

    private final int value;
    Grade(int value) { this.value = value; }
    public int getValue() { return value; }
}

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

  • EnumSet은 내부적으로 비트 연산 기반이라 빠르면서도 안전하다.
  • 권한, 옵션 등 다중 선택 가능한 enum에서 활용하면 깔끔하고 효율적이다.
1
2
3
public enum Permission { READ, WRITE, EXECUTE }

EnumSet<Permission> perms = EnumSet.of(Permission.READ, Permission.WRITE);

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

  • 배열 인덱스로 enum을 쓰는 것보다 EnumMap이 더 명확하고 안전하다.
  • 통계, 설정, 매핑 테이블 등에 EnumMap 쓰면 성능과 가독성 둘 다 잡는다.
1
2
Map<DayOfWeek, String> dayNames = new EnumMap<>(DayOfWeek.class);
dayNames.put(DayOfWeek.MONDAY, "월요일");

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

  • enum은 상속 불가 → 여러 타입에서 동작 통일하려면 인터페이스를 활용하자.
  • 전략 패턴에서 인터페이스 + enum 조합을 잘 쓰면 코드 관리가 쉬워진다.
1
2
3
4
5
6
7
8
public interface DiscountPolicy {
    int discount(int amount);
}

public enum BasicPolicy implements DiscountPolicy {
    FIXED { public int discount(int amount) { return 1000; } },
    RATE { public int discount(int amount) { return amount / 10; } }
}

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

  • 애너테이션은 명시적이고 안정적이며, 도구와의 연동도 좋다.
  • JUnit, Spring, Lombok 등 거의 모든 프레임워크가 애너테이션 기반으로 움직인다.
1
2
3
4
@Test
public void shouldReturnTrueWhenInputIsValid() {
    ...
}

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

  • 오버라이딩 시 실수를 막고, IDE도 도움을 줄 수 있다.
  • 인터페이스 구현에도 붙이는 게 좋다(Java 6 이상).
  • 빠진 오버라이드 때문에 아무 일도 안 하는 버그가 종종 생긴다. 무조건 붙이자!
1
2
3
4
@Override
public void run() {
    ...
}

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

  • interface는 타입 체크가 가능하고 문서화도 쉽다.
  • @Marker 애너테이션은 런타임만 확인 가능하다.
  • 단순한 구분이지만, instanceof로 분기처리할 수 있다는 점에서 활용도가 높다.
1
public interface FastSerializable extends Serializable {}
This post is licensed under CC BY 4.0 by the author.