Skip to content

Latest commit

 

History

History
145 lines (91 loc) · 5.24 KB

정의하려는_것이_타입이라면_마커_인터페이스를_사용하라(김형주).md

File metadata and controls

145 lines (91 loc) · 5.24 KB

🤔 마커 인터페이스(marker interface)란?

  • 아무 메서드도 선언하지 않은 인터페이스를 말한다.

  • 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 역할을 한다.

  • 대표적으로 Clonealbe, Serializable이 있다.

마커 인터페이스 예시

public class TestObjcet{
    private String name;
    private String email;
    
    public TestObjcet(String name, String email) {
        this.name = name;
        this.email = email;
    }
    
    public static void main(String[] args){
        final TestObjcet obj = new TestObjcet("kim", "[email protected]");
        // clone() 사용
        final Object clone = obj.clone();
        System.out.println("clone.toString() = " + clone.toString());
    }
}

실행 결과

Exception in thread "main" java.lang.CloneNotSupportedException:
	at java.base/java.lang.Object.clone(Native Method)
	at main.effective_java.stage_6.item_41.TestObjcet.main(TestObjcet.java:22)
  • Cloneable 인터페이스를 가지지 않은 객체를 clone()할 경우, 위와 같이 CloneNotSupportedException을 발생시킨다.

Cloneable 사용 예시

public interface Cloneable {    // 아무것도 정의되어 있지 않다.
}

public class TestObjcet implements Cloneable{
    ...
  
    public static void main(String[] args){
        final TestObjcet obj = new TestObjcet("kim", "[email protected]");
        // clone() 사용
        final Object clone = obj.clone();
        System.out.println("clone.toString() = " + clone.toString());
    }
}

실행 결과

clone.toString() = TestObjcet{name='kim', email='[email protected]'}
  • 이번에는 Cloneable 인터페이스를 붙여주고 실행해주면, 올바르게 복제되는 것을 확인할 수 있다.

  • Cloneable 인터페이스는 "나 clone() 가능한 클래스야~" 라고 알리는 셈인다.

  • 이처럼 아무 메서드도 없고, 특정 속성을 가졌다는 것 알리는 역할을 하는 인터페이스를 마커 인터페이스라고 한다.

🎯 마커 애너테이션

마커 애너테이션 예시

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
  • 마커 인터페이스와 동일하게 아무 메서드도 가지지 않은 애너테이션을 말한다.

  • 아래와 같은 meta-annotaiton(메타 애너테이션)을 이용해 만든다.

  • @Target : 해당 애너테이션을 어디에 적용시킬지 정한다.

  • @Retention : 해당 어네테이션이 적용되고 유지되는 범위를 정한다.

meta-annotaiton(메타 애너테이션) 이란?

다른 애너테이션에서도 사용되는 애너테이션을 말한다.

예를 들어, @Service 안에 들어가있는 @Component, @Target, @Retention 등을 말한다.

마커 인터페이스 🆚 애너테이션

마커 애너테이션이 등장하면서 마커 인터페이스는 구식이 되는 것 같지만

실제로는 2가지 면에서 마커 인터페이스가 애너테이션보다 장점을 가지고 있다.

1️⃣ 마커 인터페이스는 클래스의 인스턴스들을 구분하는 타입으로 사용할 수 있다.

  • 마커 인터페이스는 어엿한 타입이다.

  • 만약 인스턴스를 잘못사용했다면, 마커 인터페이스의 경우는 컴파일 단계에서 문제를 발견할 수 있다.

  • 하지만 애너테이션의 경우, 컴파일이 아닌 런타임 단계에서 문제가 발생한다.

2️⃣ 인터페이스는 적용 대상을 더 정밀하게 지정할 수 있다.

  • 마커 애너테이션을 정의할때, 만약 @TargetElementType.TYPE으로 선언한다면 모든 타입에 달 수 있다.

  • 모든 타입 : 클래스, 인터페이스, 열거 타입, 애너테이션

  • 즉, 타입을 더 세밀하게 제한하지 못한다.

🧐 하지만 마커 애너테이션은 거대한 애너테이션 시스템의 지원을 받을 수 있다는 장점을 가지고 있다.

그래서 애너테이션을 적극사용하는 프레임워크에서는 애너테이션이 더 유리할 수 도 있다.

📝 정리

🤷‍♂️ 그렇다면 우리는 어떤 기준으로 선택하는 것이 좋을까?

아래의 질문들에 답해보면서 인터페이스 혹은 애너테이션을 고르면 좋을 것 같다.

  • 만약 마킹이 된 객체를 매개변수로 주고 받는 경우가 존재하는가?

    • 이 경우, 인터페이스가 유리하다.
    • 인터페이스을 사용하면 적용대상을 더 정밀하제 지정할 수 있고, 컴파일 단계에서 문제를 잡을 수 있다.
  • 만약 클래스와 인터페이스 외의 프로그램 요소에 마킹해야되거나 애너테이션 관련 프레임워크를 사용하는가?

    • 이 경우, 애너테이션이 유리하다
    • 클래스와 인터페이스만이 인터페이스를 구현하거나 확장할 수 있기 때문이다.

📚 Reference