본문 바로가기
백엔드/스프링 프레임워크 & 스프링 부트

JSpecify와 스프링 프레임워크 7에서의 적용

by slowcloud_ 2025. 7. 12.

tl;dr

  • 스프링 프레임워크 7부터, null 체크 시 JSR-305를 더 이상 사용하지 않고 JSpecify를 사용하게 된다.
  • 7.0.0 스냅샷 Documentation에서 마이그레이션 가이드를 확인할 수 있다.

 

JSpecify는, 해당 스택 오버플로우 질문과 같이, 자바에서 null check를 위해 사용하는 어노테이션이 뿔뿔이 흩어져 있어, null check의 표준이 되고자 만들어졌다. JSpeify는 명세로, 어노테이션만을 제공하고 있으며, 각 어노테이션이 어떤 방식으로 활용되어야 하는지에 대한 설명이 이루어져 있다.

 

스프링 프레임워크 7부터, null 체크 시 JSR-305를 더 이상 사용하지 않고 JSpecify를 사용하게 된다.

 

`@NonNull`, `@Nullable`은 리턴 값, 파라미터, 제네릭 내부 등에 붙일 수 있으며, `@NonNull`은 해당 값이 절대로 null일 수 없음을 알리고, `@Nullable`은 null이 될 수 있음을 알린다.

class Example {
  void useNullable(@Nullable String x) {...}
  void useNonNull(@NonNull String x) {...}

  void example(@Nullable String nullable, @NonNull String nonNull) {
    useNullable(nonNull); // JSpecify allows this
    useNonNull(nullable); // JSpecify doesn't allow this
  }
}

 

`@NullMarked`와 `@NullUnMarked`는 클래스, 메소드 등에 붙일 수 있으며, `@NullMarked`는 반환값, 파라미터 등의 내부의 모든 요소들을 `@NonNull`한 요소들로 취급하고, `@NullUnMarked`는 `@Nullable`한 요소들로 취급한다.

@NullMarked
class Strings {
  // `@Nullable` 어노테이션을 붙여서 다시 nullable을 적용할 수도 있다.
  static @Nullable String emptyToNull(String x) {
    return x.isEmpty() ? null : x;
  }

  // 해당 파라미터도 마찬가지.
  static String nullToEmpty(@Nullable String x) {
    return x == null ? "" : x;
  }
}

 

Nullaway, 인텔리제이 IDEA 등에서 JSpecify를 지원하고 있다. 다만 제네릭에 적용한 어노테이션에 한해선 잘 작동하지 않는 모양이다.

 

참고