JAVA/Effective Java
item 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라
Garonguri
2022. 6. 14. 02:00
728x90
마커 인터페이스란?
- 아무 메서드도 담고 있지 않으며, 자신을 구현하는 클래스가 특정 속성을 가지는 것을 표시해주는 인터페이스
- 예시로는 Serializable, Cloneable interface 등이 있다.
//Serializable Interface를 봐보자!
package java.io;
public interface Serializable {
}
마커 애너테이션이란?
- 해당 요소가 특정 속성을 가지는 것을 나타내는 애너테이션
- 마커 어노테이션은 멤버를 포함하지 않으며 데이터로 구성되지 않는다.
- 마커 어노테이션의 목적은 단지 어노테이션 선언을 표시하는 것이다.
- 예시로는 @Override 등이 있다.
//@Override Annotation
package java.lang;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
Q. 마커 인터페이스가 좋을까, 마커 애너테이션이 좋을까?
A. 상황 마다 다르다.
Q. 그럼 마커 인터페이스는 어떤 면에서 마커 애너테이션보다 좋을까?
A.
- 마커 인터페이스는 마커 인터페이스를 구현한 클래스의 인스턴스를 구분하는 타입 으로 쓸 수 있다. (마커 애너테이션은 불가)
- 마커 인터페이스와 마커 애너테이션 모두 클래스가 어떠한 속성을 가진다는 표시로 쓸 수 있다.
- 마커 인터페이스는 '타입' 이기 때문에, 컴파일 타임에 오류를 찾아낼 수 있다. (마커 애너테이션은 런타임에 오류를 찾는다.)
- 마커 인터페이스를 사용하면 적용 대상을 더 정밀하게 지정할 수 있다.
- 특정 인터페이스를 구현한 클래스에만 적용하고 싶은 마커가 있고, 이를 인터페이스로 정의했다면, 마킹하고 싶은 클래스에서만 인터페이스를 구현(확장)하면 된다.
- 마킹된 타입은 자동으로 그 인터페이스의 하위 타입임이 보장된다.
- 반면, 마커 애너테이션을 사용해 적용 대상(@Target)을 Element.TYPE으로 선언한 애너테이션은 모든 타입에 달 수 있다.
- 즉, 세밀한 타입 제한이 어렵다는 이야기이다.
- 특정 인터페이스를 구현한 클래스에만 적용하고 싶은 마커가 있다면? 애너테이션만 사용해선 어렵다.
Q. 그럼 마커 애너테이션은 어떤 면에서 마커 인터페이스보다 좋을까?
A.
- 마커 애너테이션은 거대한 애너테이션 시스템의 지원을 받는다.
- 애너테이션을 적극적으로 활용하는 프레임워크에서는 애너테이션을 써 일관성을 지키는 것이 유리하다.
- 마킹하려는 곳이 클래스와 인터페이스가 아니라면 (모듈, 패키기, 필드 지역변수 등) 애너테이션을 사용하는 것이 좋다.
- 클래스와 인터페이스만이 인터페이스를 구현하거나 확장할 수 있기 때문이다.
마커를 클래스와 인터페이스에 적용해야 한다면, 적용하기 전에 자문 자답을 해보자.
"마킹이 된 객체를 매개변수로 받는 메서드를 작성할 일이 있을까??"
이 질문에 "yes"라고 답한다면 마커 인터페이스를 사용해야 한다. (컴파일 타임에 오류를 잡기 위하여)
이 질문에 "no"라고 답한다면 마커 애너테이션을 사용하자.
728x90