2023-java-study / book-study

북 스터디 기록 레포지토리
0 stars 0 forks source link

[item 39] getAnnotationType 메소드와 isAnnotationPresent #120

Open NuhGnod opened 1 year ago

NuhGnod commented 1 year ago

p. 244 getAnnotationByType 과 isAnnotationPresent의 차이점에 대해 말해주고 있습니다.

제가 이해한 것은, 반복 가능 어노테이션을 여러번 달렸는지 구별하고 못하고의 차이점이 있다고 생각했습니다. 그래서 코드 39-10에서 if (m.isAnnotationPresent(ExceptionTest.class) || m.isAnnotationPresent(ExceptionTestContainer.class)) 을 통해, 앞의 조건식에서는 한 번만 단 메서드를 뒤의 조건식은 여러번 단 메서드를 찾아주고 있습니다.


그래서 저는 이 if조건문을 getAnnotationByType 을 사용하면 안되는건가? 싶어서 한번 해봤는데, if(m.getAnnotationsByType(ExceptionTest.class) != null) 처럼, 한 번만 단 메서드여러번 단 메서드 두 형태의 메소드를 getAnnotationByType을 통해 가져올 수 있습니다. 그래서 null이라면 두개 다 없다고 볼 수 있어서 이처럼 작성해보았는데, 우선은 동작합니다.

다른분들은 이렇게 사용하는 것에 대해 어떻게 생각하시나요?

ssstopeun commented 1 year ago

여러 예시를 작성해봤는데

public class Sample3 {

    public static void m4() { }

    @ExceptionTest(IndexOutOfBoundsException.class)
    @ExceptionTest(NullPointerException.class)
    public static void doublyBad() {
        List<String> list = new ArrayList<>();

        // 자바 API 명세에 따르면 다음 메서드는 IndexOutOfBoundsException이나
        // NullPointerException을 던질 수 있다.
        list.addAll(5, null);
    }
}

이런 코드를 RunTests로 돌리게 되면 image

결과가 다음과 같았습니다. 지금 m4 메서드같은 경우에는 Test를 한다고 하지 않았는데 if(m.getAnnotationsByType(ExceptionTest.class) != null) 이부분에서 true로 되어서 들어가더라고요. 그래서 Test하지 않아야할 것 까지 Test를 해버리는 문제가 있었습니다.

그래서 m.getAnnotationsByType(ExceptionTest.class).length>0 이렇게 해봤는데... 이건 되더라고요...? 그래서 그럼 이렇게 작성하면 되는게 아닌가.....하는 멘붕에 빠져버렸네요..

일단 제가 생각한 결론은

  1. if문 안에서 반복가능한 애너테이션이 달린 것과 한번만 단 메서드들을 테스트하겠다! 고 명시하는거에 의의가 있다.
  2. 만약 반복 가능 애너테이션이 굉장히 많이 달렸을 때 annotation이 존재하는지 안하는지 검사하는 m.isAnnotationPresent(ExceptionTest.class) 에 비해 m.getAnnotationsByType(ExceptionTest.class) 는 우선 모든 애너테이션을 가져오는 것이기에 성능이 떨어질 것이다고 생각했습니다.