핵심 내용
둘 중 절대적인 정답은 없다. 프로젝트의 특성을 고려해서 마커 인터페이스와 마커 애너테이션 중 적절히 선택하자.
마커 인터페이스 vs 마커 애너테이션
마커 인터페이스
이 인터페이스를 구현한 클래스의 인스턴스들에게 어떤 특징을 부여하는 역할을 한다. 메소드를 전혀 포함하지 않는 인터페이스를 의미한다. 대표적인 예시로 Serializable 인터페이스가 있다. 이 인터페이스를 구현한 클래스의 인스턴스가 직렬화될 수 있음을 나타내는 역할을 한다.

마커 애너테이션
이 애너테이션이 달린 요소(클래스, 메소드, 필드 등)에 어떤 특징을 부여하는 역할을 한다. 멤버를 전혀 포함하지 않는 애너테이션을 의미한다. 대표적인 예로 @FunctionalInterface 애너테이션이 잇다. 이 애너테이션은 해당 인터페이스가 함수형 인터페이스임을 나타낸다. 함수형 인터페이스는 하나의 추상 메소드만을 가지는 인터페이스를 의미한다. 추상 메소드를 두 개 이상 가지면 컴파일 오류가 발생한다.

@FunctionalInterface
public interface MyFunctionalInterface {
void execute();
}
구식 같아 보이는 마커 인스페이스가 마커 애너테이션보다 좋은 점 ?
1. 마커 인터페이스는 해당 타입의 변수에 할당하거나 해당 타입을 매개변수로 받는 메소드를 호출하는 등의 타입 체크를 컴파일 타임에 수행할 수 있다. 마커 애너테이션은 이런 타입 체크 기능이 없다.
마커 애너테이션은 이런 타입 체크 기능이 없다. 애너테이션이 달린 요소가 특정 애너테이션을 가지고 있다는 사실을 확인하는 것은 주로 런타임에 이루어진다.
Serializable 인터페이스는 마커 인터페이스의 이점을 제대로 활용하지 않는다. 직렬화를 수행하는 ObjectOutputStream.writeObject() 메소드는 매개변수 타입으로 Object를 받는다. 즉, 컴파일 타임에는 Serializable 인터페이스를 구현하였는지 여부를 검사하지 않는다. writeObject() 메소드가 호출되는 런타임 때에 실제로 직렬화가 가능한지 확인한다.
2. 적용 대상을 더 정밀하게 지정할 수 있다.
@Target을 ElementType.TYPE으로 선언한 애너테이션은 모든 타입(클래스, 인터페이스, 열거 타입, 애너테이션)에 달 수 있다. 그 이상의 세밀한 제한은 할 수 없다.
만약 특정 인터페이스를 구현한 클래스에만 적용하고 싶은 마커가 있다면, 마킹하고 싶은 클래스에만 그 인터페이스를 구현하면 된다.
마커 애너테이션이 마커 인터페이스보다 좋은 점
거대한 애너테이션 시스템의 자원을 받는다.
리플랙션 API와 결합되어, 애너테이션이 붙은 클래스, 메소드 필드 등의 요소에 대한 메타데이터를 쉽게 읽고 처리할 수 있다. 또한, 애너테이션 처리 도구, 테스트 프레임워크, IDE, 빌드 도구 등과 통합되어 있어, 코드를 작성하고 테스트하고 디버깅하는 과정을 효율적으로 만들어준다.
그래서 뭐 써야됨?
클래스와 인터페이스 외의 프로그램 요소(모듈, 패키지, 필드, 지역변수 등)에 마킹해야 할 때는 애너테이션을 사용해야 한다. 인터페이스는 인터페이스와 클래스만 구현할 수 있으므로 ..
마킹이 된 객체를 매개변수로 받는 메소드를 작성할 경우, 마커 인터페이스를 사용하자. 마커 인터페이스를 해당 메소드의 매개변수 타입으로 사용하여 컴파일타임에 오류를 발견할 수 있다.
새로 추가하는 메소드 없이 단지 타입 정의가 목적이라면 마커 인터페이스를 선택하자.
애너테이션을 적극 활용하는 프레임워크에서 사용하려는 마커라면 마커 애너테이션을 사용하자.
ElementType.TYPE인 마커 애너테이션을 작성하고 있다면, 어떤 선택이 좋을지 따져봐라.
'Language > Java' 카테고리의 다른 글
| [effective java] 아이템 43. 람다보다는 메서드 참조를 사용하라. (0) | 2023.07.03 |
|---|---|
| [effective java] 아이템 42. 익명 클래스보다는 람다를 사용하라. (0) | 2023.07.02 |
| [effective java] 아이템 40. @Override 애너테이션을 일관되게 사용하라. (0) | 2023.07.02 |
| [effective java] 아이템 39. 명명 패턴보다 애너테이션을 사용하라. (0) | 2023.07.02 |
| [effective java] 아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라. (0) | 2023.07.02 |