ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • javax.annotation.* (jsr 305)
    카테고리 없음 2023. 4. 22. 14:39
    오늘은 jsr305 스펙에 대해서 몇가지 알아보자. jsr305 는 소프트웨어 결함 탐지를 위한 어노테이션이다. 이렇게 말하면 뭔말인지 모르니 한번 해보도록하자. com.google.code.findbugs 의 jsr305를 디펜더스 받자. 왜 google로 되어있는지는 모르겠다. 만든 사람이 구글에 다니던 시절에 만들어서 그런가? findbugs 프로젝트보면 다양한게 많이 있는 듯한데.. 자세히는 보지 않았다. 일단 아래와 같이 디펜더시를 받자.
    <dependency>
        <groupId>com.google.code.findbugs</groupId>
        <artifactId>jsr305</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    그리고 나서 하나씩 살펴보도록 하자. 일단 기준은 IDEA이다. 이클립스나 넷빈즈는 어떻게 동작하지는 잘 모르겠다. 스펙들은 아주 많은데 그 중에 IDEA가 지원해주거나 혹은 자주 사용할 것 같은 어노테이션 위주로 살펴보도록 할 것이다.

    @Nonnull

    null이 아님을 의미한다. 이 어노테이션이 붙는 다면 null이 아니여야 한다. 파라미터나 리턴(메서드위)에 이 어노테이션을 넣을 수 있다. 인텔리 기준에서는 해당 메서드를 호출시 힌트가 발생한다.
    public static int getLength(@Nonnull String name) {
      return name.length();
    }
    
    만약 위와 같은 코드가 있을 때 꼭 null이 아니여야 하므로 이 코드를 호출시에 null을 넣으면 경고(?) 힌트가 발생한다.
    getLength(null); // null 에 힌트 
    
    또 한 이렇게 메서드를 호출시에는 NPE이 발생하지 않고 다른 에러가 발생한다.
    Exception in thread "main" java.lang.IllegalArgumentException: Argument for @Nonnull parameter name of me/wonwoo/ClassTest.getLength must not be null
    
    
    위와 같은 에러? 실제 컴파일을 해서 바이트코드를 보면 null 체크하는 코드가 삽입되서 들어간다. 파라미터뿐만 아니라 리턴타입에 넣어도 된다.
    @Nonnull
    public static Integer getLength(@Nonnull String name) {
      return null;  //null 에 힌트
    }
    

    @Nullable

    @Nonnull 어노테이션과는 반대의 의미를 가지고 있다. null이 가능하다는 것을 의미한다. 역시 파라미터뿐 아니라 리턴타입에도 넣을 수 있다.
    @Nullable
    public static Integer getLength(@Nullable String name) {
      return name.length(); // 힌트
    }
    
    final Integer length = getLength("null");
    length.toString(); //힌트
    
    
    파라미터 name은 null이 들어 올 수 있으므로 NPE 발생할 여지가 있다. 그래서 length()를 그대로 호출 하면 안된다는 것이다.

    @CheckReturnValue

    위 어노테이션은 리턴 값 꼭 받아서 확인하라는 어노테이션이다.
    @CheckReturnValue
    public static Integer getLength(String name){
      return name.length();
    }
    
    getLength("null"); //힌트
    
    getLength() 메서드를 호출할 때 리턴을 받지 않아 힌트가 주어졌다.

    @OverridingMethodsMustInvokeSuper

    이 어노테이션은 만약 슈퍼클래스의 메서드를 오버라이딩 할 때 꼭 슈퍼 클래스의 메서드를 호출 하라는 뜻 이다.
    class SuperClass {
      @OverridingMethodsMustInvokeSuper
      public String name() {
        return "wonwoo";
      }
    }
    
    class SubClass extends SuperClass {
    
      @Override
      public String name() { //메서드 힌트
        return "won";
      }
    }
    
    SuperClass의 name 메서드를 오버라이딩 했지만 SuperClass의 name() 메서드를 호출하지 않아 메서드에 힌트가 발생하였다.

    @ParametersAreNullableByDefault

    @Nonnull 과 동일한 거 같은데? 이것은 파라미터에만 적용된다.
    @ParametersAreNullableByDefault
    public static List<String> lists(List<String> list) {
      if(list != null) {
        list.size();
      }
      list.size(); //힌트
      return list
    }
    
    파리미터 List<String> list 는 null이 가능하므로 if 문 밖에 있는 list.size()에 힌트가 주어졌다. null이 가능하므로 null 체크를 해줘야 할 것이다.

    @ParametersAreNonnullByDefault

    @ParametersAreNullableByDefault 이 어노테이션과는 반대되는 어노테이션이다. 파라미터가 null이 아니여야 한다는 뜻이다.
    @ParametersAreNonnullByDefault
    public static List<String> lists(List<String> list) {
      if(list != null) { //힌트
        list.size();
      }
      list.size();
      return list;
    }
    
    파라미터가 null이 아니여야 하므로 굳이 null 체크를 할 필요가 없다는 뜻이다. 그래서 null 체크 부분에서 힌트가 주어졌다. 일단 jsr305 어노테이션을 IDEA가 지원해주는 것은 여기까지 인 듯 하다. 더 있을 수는 있겠지만 그닥 사용하지 않을 듯 해서 살펴보지 않았다. 지원은 해주지 않지만 자주 사용할만한 어노테이션은 @Immutable, @NotThreadSafe, @ThreadSafe 이정도가 더 있을 듯하다. 이런 어노테이션을 통해 어느정도는 버그들을 잡을수(?) 있을 듯 하다. nullPointException만 잡아도 어느정도(?) 버그는 잡지 않을까? 예전에 어느 기사였나 블로그 였나? 자바의 가장 많이 발생하는 exception이 nullPointException이라 했던 기억이 어렴풋이 난다. 암튼 null이란.. 아무튼 이렇게 jsr305 어노테이션을 사용해서 아니 @Nonnull, @Nullable 이정도면 사용해도 어느정도 괜찮을 듯 하다. null 만이라도 잡자!

    댓글

Designed by Tistory.