JAVA/Effective Java

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

꾸준함. 2024. 2. 29. 00:20

마커 인터페이스

  • 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해 주는 인터페이스
  • ex) Serializable
    • 아무런 메서드도 없지만
    • 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸 수 있다 즉, 직렬화할 수 있다고 알려줌

 

 

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

 

1. 마커 인터페이스

 

장점

  • 마커 어노테이션과 달리 마커 인터페이스를 구현한 클래스의 인스턴스를 구분하는 타입으로 사용 가능
  • 컴파일 시점에 오류 발견 가능
  • 마커 어노테이션에 비해 적용 대상을 더 정밀하게 지정 가능
    • 적용 대상을 @Target(ElementType.TYPE)으로 선언한 어노테이션은 모든 타입(클래스, 인터페이스, Enum 타입, 어노테이션)에 달 수 있지만 부착할 수 있는 타입을 더 세밀하게 제한 못함
    • 반면, 마커 인터페이스의 경우 단순히 마킹하고 싶은 클래스에만 해당 인터페이스를 구현하면 됨 (마킹된 타입은 자동으로 그 인터페이스의 하위 타입을 보장)

 

  • 마커 인터페이스는 객체의 특정 부분을 불변식으로 규정하거나, 그 타입의 인스턴스는 다른 클래스의 특정 메서드가 처리할 수 있다는 사실을 명시하는 용도로 사용 가능
    • ex) Serializable 인터페이스가 ObjectOutputStream이 처리할 수 있는 인스턴스

 

단점

  • 마커 인터페이스를 사용하는 주목적이 컴파일 시점에 오류를 발견하는 것인데 ObjectOutputStream.writeObject 메서드를 사용할 경우 장점을 살리지 못함
    • ObjectOutputStream.writeObject 메서드는 매개변수에 Serializeable 인터페이스 구현체가 넘겨져야 한다고 가정하지만 실상은 Object로 받음
    • Serializable을 구현한 매개변수가 와도 컴파일 에러 발생 X
    • 하지만 런타임에 Serializable 타입이 아니라는 에러를 발생 시킴 (NotSerializableException)

 

 

2. 마커 어노테이션

 

장점

  • 어노테이션 기반의 프레임워크에서는 거대한 어노테이션 시스템을 지원하기 때문에 마커 어노테이션을 쓰는 쪽이 더 나음
  • 모듈, 패키지, 필드, 지역변수와 같이 클래스 외의 프로그램 요소에 마킹해야 할 경우 마커 인터페이스를 쓸 수 없으므로 마커 어노테이션을 사용할 수밖에 없음

 

단점

  • 마커 인터페이스와 달리 인스턴스 구분 못함
  • 오류를 컴파일 타임에 발견 못하고 런타임에 발견함
  • 적용 대상을 @Target(ElementType.TYPE)으로 선언한 어노테이션은 모든 타입(클래스, 인터페이스, Enum 타입, 어노테이션)에 달 수 있지만 부착할 수 있는 타입을 더 세밀하게 제한 못함

 

정리

  • 마커 인터페이스와 마커 어노테이션은 각각의 용도와 각자의 장단점을 가지고 있음
  • 새로 추가하는 메서드는 없지만 단지 타입 정의가 목적이라면 마커 인터페이스를 사용하는 것을 권장
  • 마커 어노테이션을 사용할 때 @Target(ElementType.TYPE)인 마커 어노테이션을 작성하고 있는데 마커 인터페이스로 대체 가능하다면 타입 안전성 보장을 위해 마커 인터페이스 사용을 권장

 

참고

이펙티브 자바

반응형