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

마커 인터페이스

  • 아무 메서드도 담고 있지 않고 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스

  • Serializeable은 자신을 구현한 클래스의 인스턴스는 직렬화할 수 있음을 알려주는 역할을 한다.

마커 인터페이스 vs 마커 어노테이션

마커 인터페이스의 장점

  1. 구현 클래스의 인스턴스를 구분하는 타입으로 사용 가능

  • 마킹된 객체를 매개변수로 받는 메서드가 있을때, 마커 인터페이스를 사용하면 타입 검사가 가능하다.

  • 마커 인터페이스는 타입이기 때문에, 마커 어노테이션을 사용했다면 런타임에야 발견될 오류를 컴파일 타임에 잡아낼 수 있다.

  • 예를 들어 ObjectOutputStream.writeObject 메서드의 인수로 받은 객체는 Serializable을 구현해야 한다. 따라서 Serializable 인터페이스를 구현한 객체를 받도록 하면 컴파일타임에 오류를 검출할 수 있다. 하지만 이 메서드는 Object 객체를 받도록 설계되어 있어 Serializable을 구현하지 않은 객체를 넘겨도 런타임에야 문제가 발생한다. (마커 인터페이스의 득을 보지 못하는 방식..)

/**
...
 * Exceptions are thrown for problems with the OutputStream and for
 * classes that should not be serialized.
 */
public final void writeObject(Object obj) throws IOException {
...
}
  1. 적용 대상을 정밀하게 지정 가능

  • 마커 어노테이션은 적용 대상을 @Target(ElementType.Type)으로 적용할 수 있는데, ElementType.Type은 클래스, 인터페이스, 열거 타입, 애너테이션 등 모든 타입에 애너테이션을 달 수 있다. 하지만 세밀하게 적용 범위를 제한할 수는 없다.

  • 마커 인터페이스는 특정 구현 클래스에만 적용 가능하다.

  • 마킹하고 싶은 클래스만 해당 마커 인터페이스를 구현하면 된다.

마커 어노테이션의 장점

  1. 거대한 어노테이션 시스템의 지원을 받을 수 있다.

어노테이션을 적극 활용하는 프레임워크에서는 마커 어노테이션을 사용해 일관성을 지키는 것이 좋다.

  1. 클래스와 인터페이스 외의 프로그램 요소에 마킹해야 할 때에는 어노테이션을 사용해야 한다.

  • 클래스와 인터페이스만 인터페이스를 구현/확장할 수 있기 때문에, 다른 요소들은 인터페이스 사용이 불가능하다.

  • 모듈, 패키지, 필드, 지역변수 등에 마킹할 때에는 어노테이션을 사용할 수 있다.

Last updated