Java

[Effective Java] 6-3. 열거 타입과 애노테이션

noahkim_ 2024. 12. 31. 02:27

조슈아 블로크 님의 "Effective Java" 책을 정리한 포스팅 입니다.

 

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

@Override

  • 상위 타입의 메서드를 재정의하였음을 뜻함
  • 추상메서드를 재정의한 경우, 애너테이션을 달지 않아도 됨

 

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

마커 인터페이스

public interface Auditable {
}

public class User implements Auditable {
    private String name;
    private int age;

    // 생성자와 Getter/Setter
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • 단지 자신을 구현하는 클래스의 특징을 나타내는 인터페이스
  • 아무 메서드도 담지 않음

 

장점
public class AuditService {
    public void audit(Object obj) {
        if (obj instanceof Auditable) {
            System.out.println("Auditing: " + obj.toString());
        } else {
            System.out.println("Object not auditable.");
        }
    }
}
  • 컴파일 타임에 타입 안정성 체크 가능
  • 적용 대상을 더 정밀하게 지정할 수 있음
    • 클래스, 인터페이스만 사용됨

 

예시
  • Serializable

 

vs 마커 애노테이션

public class AuditService {
    public void audit(Object obj) {
        if (obj.getClass().isAnnotationPresent(Auditable.class)) {
            System.out.println("Auditing: " + obj.toString());
        } else {
            System.out.println("Object not auditable.");
        }
    }

    public static void main(String[] args) {
        User user = new User("Alice", 25);
        AuditService service = new AuditService();

        service.audit(user);  // Auditing: User@12345
        service.audit("String Object");  // Object not auditable.
    }
}
장점
  • 애너테이션 시스템의 지원을 받을 수 있음
    • 리플렉션으로 런타임에서 메타데이터에 접근 가능
  • 다양한 프로그램 요소에 적용 가능
    • 모듈, 패키지, 필드 등