도당탕탕

Item41 : 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 본문

JAVA

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

backlo 2023. 1. 2. 15:30

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

대표적인 예로 Serializable 인터페이스가 있다. Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸 수 있다는, 즉 직렬화할 수 있다고 알려준다.

마커 인터페이스의 장점

마커 애너테이션이 신식이라 말하고 마커 인터페이스보다 좋다고 말하는데 이는 사실이 아니다. 오히려 다음과 같이 두 가지 측면에서 마커 애너테이션보다 마커 인터페이스가 낫다고 한다.

마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나, 마커 애너테이션은 그렇지 않다.

즉 인터페이스가 어엿한 타입이므로 런타임에야 발견될 오류를 컴파일타임에 잡을 수 있다. 하지만 애너테이션은 런타임에서만 발견이 가능하다.

마커 인터페이스가 나은 점 두 번째는 적용 대상을 더 정밀하게 지정할 수 있다는 것이다.

적용 대상이 @Target을 Element.TYPE으로 선언한 애너테이션은 모든 타입에 달 수 있다. 즉 부착할 수 있는 타입을 더 세밀하게 제한한 지는 못한다는 뜻이다. 만약 이를 마커 인터페이스로 정의했다면 그냥 마킹하고 싶은 클래스에서만 인터페이스를 구현하면 된다. 그러면 마킹된 타입은 자동으로 그 인터페이스의 하위 타입임을 보장되는 것이다.

Set은 마커 인터페이스

Set 인터페이스도 일종의 마커 인터페이스로 볼 수 있다. Set은 Collection의 하위 타입에만 적용할 수 있으며, Collection이 정의한 메서드 외에는 새로 추가한 것이 없다. ( 보통 Set은 마커 인터페이스로 생각하지 않는데 그 이유는 add, equals, hashCode 등 Collection의 메서드 몇 개의 규약을 살짝 수정했기 때문이다. )

특정 인터페이스의 하위 타입에만 적용할 수 있으며, 아무 규약에도 손대지 않은 마커 인터페이스는 충분히 있음직하다. 이런 마커 인터페이스는 객체의 특정 부분을 불변식으로 규정하거나, 그 타입의 인스턴스는 다른 클래스의 특정 메서드가 처리할 수 있다는 사실을 명시하는 용도로 사용할 수 있을 것이다.

마커 애너테이션의 장점

거대한 애너테이션 시스템의 지원을 받는다는 점을 들 수 있다.

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

그렇다면 언제 어떨때 써야 할까?

마커 애너테이션은 클래스와 인터페이스 외의 프로그램 요소(모듈, 패키지, 필드, 지역변수 등)에 마킹해야 할 때는 애너테이션을 쓸 수밖에 없다. 클래스와 인터페이스만이 인터페이스를 구현하거나 확장할 수 있기 때문이다.

그리고 마커를 클래스나 인터페이스에 적용해야 한다면 이 마킹이 된 객체를 매개변수로 받는 메서드를 작성할 일이 있을까? 라고 자문해 보자. 만약 그렇다면 마커 인터페이스를 사용해 메서드의 매개변수 타입으로 사용하여 컴파일타임에 오류를 잡을 수 있다.

이런 메서드를 작성할 일이 절대 없다고 확신하면 마커 애너테이션을 사용하자. 추가로 애너테이션을 활발히 활용하는 프레임워크에서 사용하려는 마커라면 마커 애너테이션을 사용하는 편이 좋을 것이다.

Comments