ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 아이템41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라
    책/이펙티브자바 2021. 8. 31. 13:59

    아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스 (marker interface)라 한다.

    ex. Cloneable, Serializable

    // 그냥 비어있음.
    public interface Serializable {
    }

     

    마커 애너테이션의 예

    ex. @Override, @FunctionalInterface, @SafeVarargs, @Native

     

    Serializable 은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream 을 통해 쓸수(write) 있다고, 즉 직렬화(serialization) 할 수 있다고 알려준다.

     

    마커 인터페이스는 두 가지 면에서 마커 애너테이션보다 낫다.

    1. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나, 마커 애너테이션은 그렇지 않다.
      1. 마커 인터페이스는 어엿한 타입이기에, 마커 애너테이션을 사용했다면 런타임에야 발견될 오류를 컴파일 타임에 잡을 수 있다.
    2. 적용 대상을 더 정밀하게 지정할 수 있다.
      1. 애노테이션의 경우 @Target 선언 으로 모든 타입에 달 수 있다.
      2. 부착 할 수 있는 타입을 더 세밀하게 제한하지는 못한다는 뜻이다.
      3. 근데 특정 인터페이스를 구현한 클래스에만 적용하고 싶은 마커가 있다고 치면, 이 마커를 인터페이스로 정의했다면 그냥 마킹하고 싶은 클래스에서만 그 인터페이스를 구현하면 된다.
      4. 마킹된 타입은 자동으로 그 인터페이스의 하위 타입임이 보장되는 것이다.

     

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

    따라서 애너테이션을 적극 활용하는 프레임워크에서는 마커 애너테이션을 쓰는 쪽이 일관성을 지키는데 더 유리할 것이다.

     

    그렇다면 언제 마커 애너테이션을, 언제 마커 인터페이스를 사용하는가 ?

    • 클래스와 인터페이스 외의 프로그램 요소 (모듈, 패키지, 필드, 지역변수 등)에 마킹해야 할 때 애너테이션을 쓸 수 밖에 없다.
    • 마커를 클래스나 인터페이스에 적용해야 한다면 "이 마킹이 된 객체를 매개변수로 받는 메서드를 작성할 일이 있을까? " 를 자문해보자.
      • 그렇다 → 마커 인터페이스를 쓴다.
      • 마커 인터페이스를 해당 메서드의 매개변수 타입으로 사용하여 컴파일 타임에 오류를 잡아낼 수 있따.
      • 아니다 → 마커 애너테이션을 쓴다.
      • 추가로 애너테이션이 활발한 프레임워크라면 ? → 마커 애너테이션을 쓴다.

    결론

    • 마커 인터페이스와 마커 애너테이션은 각자의 쓰임이 있다.
    • 새로 추가하는 메서드 없이 단지 타입 정의가 목적이면 마커 인터페이스를 쓰자.
    • 클래스나 인터페이스 외의 프로그램 요소에 마킹해야 하거나, 애너테이션을 적극적으로 쓰는 프레임워크라면 마커 에너테이션을 쓰자.
    • 적용 대상이 ElementType.TYPE 인 마커 애너테이션을 작성하고 있다면, 이게 정말 애너테이션으로 구현하는게 올흥ㄴ지, 혹은 인터페이스가 낫지는 않을지 곰곰이 생각해보자.
킹수빈닷컴