본문 바로가기
Language/Effective java

열거 타입과 애너테이션

by y.j 2022. 7. 20.
728x90

명명 패턴보다 애너테이션을 사용하라

명명 패턴보다 애너테이션을 사용해야 하는 이유가 여러가지 있다.

  • 오타가 나면 안된다.
  • 올바른 프로그램 요소에서만 사용되라는 보장이 없다.
  • 프로그램 요소를 매개변수로 전달할 마땅한 방법이 없다.

 

애너테이션 선언 방법

애너테이션 선언에 달려있는 애너테이션을 매타 애너테이션이라고 한다. @Retention은 생애주기 관련된 것이고, @Target은 타입에 관련된 매나 애너테이션이다. 

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
}

@Target(ElementType.METHOD) : Test애노테이션을 Method에만 달 수 있다는 의미

@Retention(RetentionPolicy.RUNTIME) : 런타임에도 유지되어야 한다는 의미

 

아래코드에 @Test를 붙이지 않은 메서드들은 무시가 되고 m5는 정적 메서드가 아니기 때문에 잘못 사용한 것이고, m3, m5는 예외처리를 하였기 때문에 예외가 발생한다.

public class Sample {
    @Test public static void m1() {}  // 성공
    public static void m2() {}        
    @Test public static void m3() {   // 실패
        throw new RuntimeException("실패");
    }  
    public static void m4() {}
    @Test public void m5() {}        // 정적 사용한 예 : 정적 메서드가 아니다.
    public static void m6() {}
    @Test public static void m7() {
        throw new RuntimeException("실패");
    }
    public static void m8() {}
}

 

특정 예외를 던져야만 성공하는 테스트 예제

위 예제와는 다르게 특정 예외처리를 해야만 메서드가 성공하도록 할 수 있다. 

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
    Class<? extends Throwable> value();
}

 

m1은 성공한다.

m2는 ArithemticException이 아니므로 실패한다.

m3는 예외처리가 없어서 실패한다.

public class Sample2 {
    @ExceptionTest(ArithmeticException.class)
    public static void m1() {
        int i = 0;
        i = i / i;
    }

    @ExceptionTest(ArithmeticException.class)
    public static void m2() {
        int[] a = new int[0];
        int i = a[1];
    }

    @ExceptionTest(ArithmeticException.class)
    public static void m3() {}
}

 

배열로 정의하여 여러가지 Exception처리도 가능하다.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
    Class<? extends Throwable>[] value();
}

 

@Repeatable 매타애너테이션 사용하는 방법

1. @Repeatable을 단 애너테이션을 반환하는 '컨테이너 애너테이션'을 하나 정의하고, 인자로 컨테이너 클래스를 전달해준다.

2. 컨테이너 애너테이션은 내부에 애너테이션 타입의 배열을 반환하는 value 메서드를 정의해야 한다.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(ExceptionTestContainer.class)
public @interface ExceptionTest {
    Class<? extends Throwable> value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTestContainer {
    ExceptionTest[] value();
}

 

728x90

'Language > Effective java' 카테고리의 다른 글

람다와 스트림  (0) 2022.07.24
열거 타입과 애너테이션  (0) 2022.07.23
열거 타입과 애너테이션  (0) 2022.07.18
열거 타입과 애너테이션  (0) 2022.07.13
제네릭  (0) 2022.06.26

댓글