어떤 @NotNull Java 주석을 사용해야합니까?


997

NullPointerExceptions을 피하기 위해 IDE 코드 검사 및 정적 코드 분석 (FindBugs 및 Sonar)과 같은 툴링을 사용하고 코드를 더 읽기 쉽게 만들고 싶습니다. 많은 도구가 서로의 @NotNull/ @NonNull/ @Nonnull주석과 호환되지 않는 것처럼 보이며 내 코드에 모든 도구를 나열하는 것은 끔찍할 것입니다. 어느 것이 '최고'인지에 대한 제안? 내가 찾은 동등한 주석 목록은 다음과 같습니다.

  • javax.validation.constraints.NotNull
    정적 분석이 아닌 런타임 유효성 검사를 위해 작성되었습니다.
    선적 서류 비치

  • edu.umd.cs.findbugs.annotations.NonNull
    에서 사용 Findbugs 때문에 정적 분석 및 수중 음파 탐지기 (지금 Sonarqube )
    문서

  • javax.annotation.Nonnull
    이것은 Findbugs에서도 작동하지만 JSR-305 는 비활성화되어 있습니다. ( JSR 305의 상태는 무엇입니까? 참조 ) source

  • org.jetbrains.annotations.NotNull
    정적 분석을 위해 IntelliJ IDEA IDE에서 사용합니다.
    선적 서류 비치

  • lombok.NonNull
    Project Lombok 에서 코드 생성을 제어하는 ​​데 사용됩니다 .
    표준이 없으므로 자리 표시 자 주석
    소스 , 문서

  • android.support.annotation.NonNull
    지원 주석 패키지 설명서를 통해 제공되는 Android에서 마커 주석 사용 가능

  • org.eclipse.jdt.annotation.NonNull
    정적 코드 분석 문서를 위해 Eclipse에서 사용


203
아파치는 "공통"주석과 다른 주석으로 변환 할 수있는 도구를 개발해야한다. 너무 많은 표준 문제에 대한 해결책은 새로운 표준을 발명하는 것입니다.
— 명백한

6
아파치가 새로운 "공통"을 발명하면 @irreputable, 다른 프로젝트와 겹치는 56 개의 버전이있을 것이다. 그리고 어쨌든 표준이 아닙니다 (표준! = 널리 퍼짐). 실제로 표준 인 javax?. *를 사용하는 것이 좋습니다. BTW, 그 예에는 "너무 많은 표준"이 없으며, 단지 1 또는 2 만 볼 수 있습니다.
— ymajoros

6
javax.annotation.Nonnull은 findbugs와 함께 작동합니다 (방금 테스트 한 것). 그것을 사용해야하는 강력한 이유입니다.
— Nicolas C

20
단순히 @NotNull을 쓰면 참조합니다 com.sun.istack.internal.NotNull. 세상에 ...
— 토마스 웰러

3
@MozartBrocchini-옵션은 이전에 NullObject를 사용한 적이있는 경우에 유용합니다. 그들은 실제로 런타임 \ @NotNull 주석과 같은 목표를 다루지 않으며 지루한 언 래핑을 소개합니다.
— Dave

답변:


205

이후 JSR 305 (누구의 목표를 표준화하는 것이었다 @NonNull과 @Nullable) 몇 년 동안 잠복하고있다, 난 두려워 좋은 답변이 없습니다. 우리가 할 수있는 것은 실용적인 해결책을 찾는 것입니다.

통사론

순수한 스타일 관점에서 IDE, 프레임 워크 또는 Java 자체를 제외한 툴킷에 대한 언급을 피하고 싶습니다.

이것은 배제한다 :

  • android.support.annotation
  • edu.umd.cs.findbugs.annotations
  • org.eclipse.jdt.annotation
  • org.jetbrains.annotations
  • org.checkerframework.checker.nullness.qual
  • lombok.NonNull

어느 하나 우리 잎 javax.validation.constraints이나 javax.annotation. 전자는 JEE와 함께 제공됩니다. 이것이 javax.annotationJSE와 함께 제공되거나 전혀 제공되지 않는 것보다 낫다면 논쟁의 여지가 있습니다. javax.annotationJEE 의존성이 마음에 들지 않기 때문에 개인적으로 선호합니다 .

이것은 우리를 떠나

javax.annotation

또한 가장 짧은 것입니다.

더 좋은 구문은 하나뿐입니다 java.annotation.Nullable. 다른 패키지를 졸업대로 javax에 java과거의 javax.annotation의 오른쪽 방향으로 단계가 될 것입니다.

이행

나는 그들이 기본적으로 모두 동일한 사소한 구현을 가지기를 바랐지만 자세한 분석은 이것이 사실이 아니라는 것을 보여주었습니다.

유사점 우선 :

@NonNull주석 모든 라인을 가지고

public @interface NonNull {}

제외하고

  • org.jetbrains.annotations그것을 호출 @NotNull하고 사소한 구현이 있습니다.
  • javax.annotation 더 긴 구현이 있습니다
  • javax.validation.constraints또한 그것을 호출 @NotNull하고 구현이 있습니다.

@Nullable주석 모든 라인을 가지고

public @interface Nullable {}

org.jetbrains.annotations사소한 구현으로 (다시)를 제외하고 .

차이점을 위해 :

눈에 띄는 것은

  • javax.annotation
  • javax.validation.constraints
  • org.checkerframework.checker.nullness.qual

모두 런타임 주석 ( @Retention(RUNTIME))이 있지만

  • android.support.annotation
  • edu.umd.cs.findbugs.annotations
  • org.eclipse.jdt.annotation
  • org.jetbrains.annotations

컴파일 시간 ( @Retention(CLASS))입니다.

이 SO 답변에 설명 된 것처럼 런타임 주석의 영향은 생각보다 작지만 컴파일 시간 외에도 도구를 사용하여 런타임 검사를 수행 할 수 있다는 이점이 있습니다.

또 다른 중요한 차이점은 어디에 코드에서 주석을 사용할 수 있습니다. 두 가지 접근 방식이 있습니다. 일부 패키지는 JLS 9.6.4.1 스타일 컨텍스트를 사용합니다. 다음 표는 개요를 제공합니다.

                                필드 방법 매개 변수 LOCAL_VARIABLE 
android.support.annotation XXX   
edu.umd.cs.findbugs.annotations XXXX
org.jetbrains.annotation XXXX
롬복 XXXX
javax.validation.constraints XXX   

org.eclipse.jdt.annotation, javax.annotation그리고 org.checkerframework.checker.nullness.qual그것을 할 올바른 방법은 내 의견에 JLS 4.11에 정의 된 컨텍스트를 사용합니다.

이것은 우리를 떠나

  • javax.annotation
  • org.checkerframework.checker.nullness.qual

이 라운드에서.

암호

자세한 내용을 직접 비교할 수 있도록 아래에 모든 주석의 코드를 나열합니다. 비교를 쉽게하기 위해 주석, 가져 오기 및 @Documented주석을 제거했습니다 . (모두 @DocumentedAndroid 패키지의 클래스를 제외하고) 나는 라인과 @Target필드를 재정렬하고 자격을 정규화했습니다.

package android.support.annotation;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER})
public @interface NonNull {}

package edu.umd.cs.findbugs.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}

package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface NonNull {}

package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NotNull {String value() default "";}

package javax.annotation;
@TypeQualifier
@Retention(RUNTIME)
public @interface Nonnull {
    When when() default When.ALWAYS;
    static class Checker implements TypeQualifierValidator<Nonnull> {
        public When forConstantValue(Nonnull qualifierqualifierArgument,
                Object value) {
            if (value == null)
                return When.NEVER;
            return When.ALWAYS;
        }
    }
}

package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf(MonotonicNonNull.class)
@ImplicitFor(
    types = {
        TypeKind.PACKAGE,
        TypeKind.INT,
        TypeKind.BOOLEAN,
        TypeKind.CHAR,
        TypeKind.DOUBLE,
        TypeKind.FLOAT,
        TypeKind.LONG,
        TypeKind.SHORT,
        TypeKind.BYTE
    },
    literals = {LiteralKind.STRING}
)
@DefaultQualifierInHierarchy
@DefaultFor({TypeUseLocation.EXCEPTION_PARAMETER})
@DefaultInUncheckedCodeFor({TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND})
public @interface NonNull {}

완성을 위해 @Nullable구현은 다음과 같습니다.

package android.support.annotation;
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {}

package edu.umd.cs.findbugs.annotations;
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
@Retention(CLASS)
public @interface Nullable {}

package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface Nullable {}

package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface Nullable {String value() default "";}

package javax.annotation;
@TypeQualifierNickname
@Nonnull(when = When.UNKNOWN)
@Retention(RUNTIME)
public @interface Nullable {}

package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf({})
@ImplicitFor(
    literals = {LiteralKind.NULL},
    typeNames = {java.lang.Void.class}
)
@DefaultInUncheckedCodeFor({TypeUseLocation.RETURN, TypeUseLocation.UPPER_BOUND})
public @interface Nullable {}

다음 두 패키지에는가 없으므로 @Nullable별도로 나열합니다. 롬복은 꽤 지루 @NonNull합니다. 에서 javax.validation.constraints(가) @NonNull실제로이며 @NotNull 그것은 기름 한 구현이있다.

package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}

package javax.validation.constraints;
@Retention(RUNTIME)
@Target({ FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Constraint(validatedBy = {})
public @interface NotNull {
    String message() default "{javax.validation.constraints.NotNull.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}

지원하다

내 경험상, javax.annotation적어도 Eclipse와 Checker Framework는 기본적으로 지원됩니다.

요약

이상적인 주석은 java.annotationChecker Framework 구현 의 구문입니다.

Checker Framework를 사용하지 않으 려면 당분간 javax.annotation( JSR-305 )이 가장 좋습니다.

Checker Framework에 기꺼이 구매하려는 경우을 사용하십시오 org.checkerframework.checker.nullness.qual.


출처

  • android.support.annotation ...에서 android-5.1.1_r1.jar
  • edu.umd.cs.findbugs.annotations ...에서 findbugs-annotations-1.0.0.jar
  • org.eclipse.jdt.annotation ...에서 org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
  • org.jetbrains.annotations ...에서 jetbrains-annotations-13.0.jar
  • javax.annotation ...에서 gwt-dev-2.5.1-sources.jar
  • org.checkerframework.checker.nullness.qual ...에서 checker-framework-2.1.9.zip
  • lombok에서 lombok커밋f6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
  • javax.validation.constraints ...에서 validation-api-1.0.0.GA-sources.jar

7
단점은 javax.annotationa) 죽은 JSR을 기반으로하고 b) 주석 만 제공하고 유지 관리되는 아티팩트를 찾기가 어렵다는 것입니다. findbugs의 것이 아닙니다 : search.maven.org/…
— robinst

18
다른 javax.annotation모듈은 다른 모듈도 해당 패키지 (jax-ws)의 클래스를 제공하기 때문에 Java 9에 문제가 발생한다는 것입니다.
— robinst

10
@kevinarpe : Findbugs 프로젝트가 종료되었으며 후속 프로젝트 인 Spotbugs가 해당 주석을 제거합니다. github.com/spotbugs/spotbugs/pull/180
— robinst

4
표준화 된 JSR 305javax.annotation.NonNull 는 스펙 리드가 AWOL을했기 때문에 완료되지 않았습니다. 오라클의 결정과는 아무런 관련이 없습니다.
— 마크 재 보류

5
jsr305.jar를 사용하지 않는 또 다른 이유는 Oracle Java 바이너리 라이센스를 명백히 위반하기 때문입니다. github.com/google/guava/issues/2960
— Flow

91

필자 는 nullness checker와 같은 결함 검사기를 구현하는 데 사용되는 형식 주석 ( JSR-308 ) 의 구현 인 Checker Framework를 매우 좋아합니다 . 나는 비교를 제공하기 위해 다른 것을 시도하지는 않았지만이 구현에 만족했습니다.

저는 소프트웨어를 제공하는 그룹과 제휴하지는 않지만 팬입니다.

이 시스템에 대해 내가 좋아하는 네 가지 :

  1. Null에 대한 결함 검사기 (@Nullable)가 있지만 불변성 및 인턴 (및 기타)에 대한 결함 검사기 도 있습니다 . 나는 첫 번째 (nullness)를 사용하고 두 번째 것을 사용하려고합니다 (불변성 / IGJ). 세 번째 방법을 시도하고 있지만 아직 장기적으로 사용하고 있는지 확실하지 않습니다. 나는 다른 체커의 일반적인 유용성을 아직 확신하지 못하지만 프레임 워크 자체가 다양한 추가 주석 및 체커를 구현하기위한 시스템이라는 것을 알고 있습니다.

  2. 그만큼 널 (Null) 검사 기본 설정은 다음과 같이 작동합니다. NEL (Null을 제외한 널 없음). 기본적으로 이는 체커가 기본적으로 @NonNull 유형을 갖는 것처럼 로컬 변수를 제외한 모든 변수 (인스턴스 변수, 메소드 매개 변수, 일반 유형 등)를 처리한다는 것을 의미합니다. 설명서에 따라 :

    NNEL 기본값은 코드에서 가장 적은 수의 명시 적 주석으로 이어집니다.

    NNEL이 작동하지 않으면 클래스 또는 메소드에 대해 다른 기본값을 설정할 수 있습니다.

  3. 이 프레임 워크를 사용하면 주석에 주석을 묶어 프레임 워크 에 대한 종속성을 만들지 않고 함께 사용할 수 있습니다 ./*@Nullable*/ . 라이브러리 또는 공유 코드에 주석을 달고 확인할 수는 있지만 프레임 워크를 사용하지 않는 다른 프로젝트에서 해당 라이브러리 / 공유 코드를 계속 사용할 수 있기 때문에 좋습니다. 이것은 좋은 기능입니다. 현재 모든 프로젝트에서 Checker Framework를 사용하는 경향이 있지만 사용에 익숙해졌습니다.

  4. 프레임 워크에는 스텁 파일을 사용하여 널 (null)에 대해 아직 주석을 달지 않은 사용하는 API 에 주석 을 달 수 있는 방법이 있습니다.


3
멋져서 사용하고 싶지만 할 수는 없습니다. 왜 GPL인가? 대신 LGPL이 아니겠습니까?
— Burkhard

13
FAQ 에 따르면 : "보다 관대 한 MIT 라이센스는 주석과 같이 자신의 프로그램에 포함시키려는 코드에 적용됩니다."
— seanf

1
링크가 현재 끊어졌습니다. 그러나 Checker Framework 사용에 대한 조언은 +1입니다.
— Paul Wagland

1
불변의 체커는 최신 릴리스에서 제외되는 것이 유감입니다.
— Franklin Yu

1
Checker 프레임 워크는 Oracle Java Tutorials 에서도 제안됩니다 .
— Quazi Irfan

55

나는 IntelliJ를 사용하는데, 이는 NPE를 생성 할 수있는 것들을 표시하는 IntelliJ에 주로 관심이 있기 때문입니다. JDK에 표준 주석이없는 것이 실망 스럽습니다. 그것을 추가하는 것에 대한 이야기가 있는데, 그것은 Java 7로 만들 수 있습니다.이 경우 선택할 수있는 것이 하나 더 있습니다!


68
업데이트 : IntelliJ는 이제 코드 강조를 위해 위의 모든 주석을 지원하므로 더 이상 IntelliJ의 주석으로 제한되지 않습니다. blogs.jetbrains.com/idea/2011/03/…
— Daniel Alexiuc

31
그리고 Eclipse Juno도 마찬가지입니다!
— jFrenetic

5
javax.annotation.Nonnull더 널리 받아 들여지지 않습니까?
— Martin

1
@DanielAlexiuc 그러나 불행히도 런타임 검사에 사용하지 않으므로 JetBrains를 사용하면 여전히 이점이 있습니다 ...
— Trejkaz

4
@Trejkaz 2016.3부터 모든 런타임 검사를 만듭니다.
— Karol S

32

Java 7 기능 목록 에 따르면 JSR-308 유형 주석은 Java 8로 연기됩니다. JSR-305 주석은 언급되지 않았습니다.

최신 JSR-308 초안 의 부록 에 JSR-305 상태에 대한 약간의 정보가 있습니다. 여기에는 JSR-305 주석이 폐기 된 것으로 보입니다. JSR-305 페이지에도 "비활성"으로 표시됩니다.

그 동안 실용적인 답변은 가장 널리 사용되는 도구가 지원하는 주석 유형을 사용하고 상황이 바뀌면 변경할 수 있도록 준비하는 것입니다.


실제로 JSR-308은 주석 유형 / 클래스를 정의하지 않으며 범위를 벗어난 것으로 생각됩니다. (그리고 JSR-305의 존재를 감안할 때 그들은 옳습니다).

그러나 JSR-308이 실제로 Java 8로 만들어지는 것처럼 보이면 JSR-305에 대한 관심이 다시 살아나더라도 놀라지 않을 것입니다. JSR-305 팀인 AFAIK는 공식적으로 업무를 포기하지 않았습니다. 그들은 2 년 이상 조용했습니다.

Bill Pugh (JSR-305의 기술 책임자)가 FindBugs의이면에 있다는 것은 흥미 롭습니다.


4
@pst-현재 일정은 Java 8이 2013 년 9 월 일반 릴리스로 예정되어 있음 -infoq.com/news/2012/04/jdk-8-milestone-release-dates
— Stephen C

2
이제 2014 년 3 월에 openjdk.java.net/projects/jdk8로 떨어졌습니다 . JSR 308은 빌드 M7에 포함되어 있습니다 ( "104-Java 유형에 대한 주석"참조).
— Stephen C

28

Android 프로젝트의 경우 android.support.annotation.NonNull및 을 사용해야합니다 android.support.annotation.Nullable. 이러한 유용한 기타 Android 관련 주석은 지원 라이브러리 에서 사용할 수 있습니다 .

에서 http://tools.android.com/tech-docs/support-annotations :

지원 라이브러리 자체에도 이러한 주석으로 주석이 달렸으므로 지원 라이브러리의 사용자로서 Android Studio는 이미 주석을 기반으로 코드를 확인하고 잠재적 인 문제를 표시합니다.


3
해당 권장 사항에 대한 정당성을 제공하는 것이 유용합니다.
— 살구

2
tools.android.com/tech-docs/support-annotations "지원 라이브러리 자체에도 이러한 주석이 주석으로 표시되어 있으므로 지원 라이브러리의 사용자 인 Android Studio는 이미 주석을 기반으로 코드를 확인하고 잠재적 인 문제를 표시합니다. "
— James Wald

3
BTW Android Studio는 javax.annotation.*주석이있는
— jsr305

19

누구나 IntelliJ 클래스를 찾고 있다면 다음을 사용하여 maven 저장소에서 가져올 수 있습니다

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>15.0</version>
</dependency> 

이것은 Intellij가 경고를 던지게하는 원인입니다.
— Upvote

현재 버전 (
— 2017 년

당신의 권리. 버전을 업데이트했습니다. 많이 바뀌지 않았다고 생각하더라도.
— Bruno Eberhard

JetBrains 주석은 런타임 동안 유지되지 않으므로 Guice @Nullable 지원은 작동하지 않습니다.
— 피터 메이저

18

JSR305와 FindBugs는 같은 사람이 작성합니다. 둘 다 잘 관리되지 않았지만 모든 주요 IDE에서 지원하고 지원하는 표준입니다. 좋은 소식은 그대로 작동한다는 것입니다.

기본적으로 @Nonnull을 모든 클래스, 메서드 및 필드에 적용하는 방법은 다음과 같습니다. 참조 https://stackoverflow.com/a/13319541/14731 및 https://stackoverflow.com/a/9256595/14731

  1. 밝히다 @NotNullByDefault
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;


    /**
     * This annotation can be applied to a package, class or method to indicate that the class fields,
     * method return types and parameters in that element are not null by default unless there is: <ul>
     * <li>An explicit nullness annotation <li>The method overrides a method in a superclass (in which
     * case the annotation of the corresponding parameter in the superclass applies) <li> there is a
     * default parameter annotation applied to a more tightly nested element. </ul>
     * <p/>
     * @see https://stackoverflow.com/a/9256595/14731
     */
    @Documented
    @Nonnull
    @TypeQualifierDefault(
    {
        ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.LOCAL_VARIABLE,
        ElementType.METHOD,
        ElementType.PACKAGE,
        ElementType.PARAMETER,
        ElementType.TYPE
    })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotNullByDefault
    {
    }

2. 각 패키지에 주석을 추가하십시오. package-info.java

@NotNullByDefault
package com.example.foo;

업데이트 : 2012 년 12 월 12 일 현재 JSR 305 는 "Dormant"로 표시됩니다. 설명서에 따르면 :

집행위원회에 의해 "휴면"으로 선정 된 JSR 또는 자연 수명이 다한 JSR.

JSR 308 이 JDK 8로 만드는 것처럼 보이고 JSR이 @NotNull을 정의하지는 않지만 첨부 된 것 Checkers Framework입니다. 이 글을 쓰는 시점 에서이 버그로 인해 Maven 플러그인을 사용할 수 없습니다 : https://github.com/typetools/checker-framework/issues/183


2
maven의 showtopper 문제가 해결되었습니다. 다시 옵션이되어야합니다.
— Marc von Renteln

Maven을 통해 FindBugs를 사용하는데 IDE에서 아무것도 수행하지 않으므로 IDE 관련 주석을 피할 수 있습니다.
— Christophe Roussy

@ChristopheRoussy 귀하의 질문은 IDE 관련입니다. 별도의 질문을여십시오.
— 길리

15

정적 분석과 런타임 분석을 구별하십시오. 내부 자료에는 정적 분석을 사용하고 코드의 공개 경계에는 런타임 분석을 사용하십시오.

널이어서는 안되는 것들 :

  • 런타임 검사 : "if (x == null) ..."(제로 의존성) 또는 @ javax.validation.NotNull (빈 유효성 검사 포함) 또는 @ lombok.NonNull (일반 및 단순) 또는 구아바 Preconditions.checkNotNull (.. 사용) .)

    • 메소드 리턴 유형 (선택 사항)에 선택적을 사용하십시오. Java8 또는 Guava입니다.
  • 정적 검사 : @NonNull 주석 사용

  • 적합한 경우 클래스 또는 패키지 레벨에서 @ ... NonnullByDefault 어노테이션을 사용하십시오. 이러한 주석을 직접 작성하십시오 (예를 쉽게 찾을 수 있음).
    • 그렇지 않으면 NPE를 피하기 위해 메소드 리턴에 @ ... CheckForNull을 사용하십시오.

이는 IDE의 경고, Findbugs 및 검사기 프레임 워크의 오류, 의미있는 런타임 예외와 같은 최상의 결과를 제공해야합니다.

정적 검사가 성숙 할 것으로 기대하지 말고 이름이 표준화되지 않았으며 다른 라이브러리와 IDE가이를 다르게 취급하므로 무시하십시오. JSR305 javax.annotations. * 클래스는 표준처럼 보이지만, 그렇지 않으며 Java9 +로 분할 패키지를 발생시킵니다.

일부 메모 설명 :

  • javax.validation. * 패키지를 가진 Findbugs / spotbugs / jsr305 주석은 Java9 +의 다른 모듈과 충돌하며 Oracle 라이센스를 위반할 수도 있습니다
  • Spotbugs 주석 여전히 (작성시 컴파일 타임에 JSR305 / findbugs 주석에 따라 https://github.com/spotbugs/spotbugs/issues/421 )
  • jetbrains @NotNull 이름은 @ javax.validation.NotNull과 충돌합니다.
  • 정적 검사를위한 jetbrains, eclipse 또는 checkersframework 주석은 Java9 이상의 다른 모듈과 충돌하지 않는다는 javax.annotations보다 이점이 있습니다.
  • @ javax.annotations.Nullable은 Findbugs / Spotbugs가 당신 (또는 IDE)이 생각하는 바를 의미하는 것은 아닙니다. Findbugs는이를 무시합니다 (멤버). 슬프지만 사실 ( https://sourceforge.net/p/findbugs/bugs/1181 )
  • IDE 외부의 정적 검사를 위해 Spotbugs (이전의 Findbugs)와 checkers framework라는 두 가지 무료 도구가 있습니다.
  • Eclipse 라이브러리에는 @NonNullByDefault가 있으며 jsr305에는 @ParametersAreNonnullByDefault 만 있습니다. 그것들은 패키지 (또는 클래스)의 모든 것에 기본 주석을 적용하는 단순한 래퍼입니다. 쉽게 자신 만의 것을 만들 수 있습니다. 패키지에 사용할 수 있습니다. 이는 생성 된 코드 (예 : 롬복)와 충돌 할 수 있습니다.
  • 다른 사람과 공유하는 라이브러리에서는 lombok을 내 보낸 종속성으로 사용하지 않아야합니다. 전이 종속성이 적을수록 좋습니다.
  • Bean 유효성 검증 프레임 워크를 사용하는 것은 강력하지만 오버 헤드가 많이 필요하므로 수동 널 점검을 피하기 만하면됩니다.
  • 필드 및 메소드 매개 변수에 선택 사항을 사용하는 것은 논란의 여지가 있습니다 (관련 기사를 쉽게 찾을 수 있음)
  • Android null 주석은 Android 지원 라이브러리의 일부이며 다른 많은 클래스와 함께 제공되며 다른 주석 / 도구와 잘 어울리지 않습니다.

Java9 이전에는 이것이 나의 추천입니다 :

// file: package-info.java
@javax.annotation.ParametersAreNonnullByDefault
package example;


// file: PublicApi
package example;

public interface PublicApi {

    Person createPerson(
        // NonNull by default due to package-info.java above
        String firstname,
        String lastname);
}

// file: PublicApiImpl
public class PublicApiImpl implements PublicApi {
    public Person createPerson(
            // In Impl, handle cases where library users still pass null
            @Nullable String firstname, // Users  might send null
            @Nullable String lastname // Users might send null
            ) {
        if (firstname == null) throw new IllagalArgumentException(...);
        if (lastname == null) throw new IllagalArgumentException(...);
        return doCreatePerson(fistname, lastname, nickname);
    }

    @NonNull // Spotbugs checks that method cannot return null
    private Person doCreatePerson(
             String firstname, // Spotbugs checks null cannot be passed, because package has ParametersAreNonnullByDefault
             String lastname,
             @Nullable String nickname // tell Spotbugs null is ok
             ) {
         return new Person(firstname, lastname, nickname);
    }

    @CheckForNull // Do not use @Nullable here, Spotbugs will ignore it, though IDEs respect it
    private Person getNickname(
         String firstname,
         String lastname) {
         return NICKNAMES.get(firstname + ':' + lastname);
    }
}

nullable 메소드 매개 변수가 참조 해제 될 때 (작성 시점에서 Spotbug 버전 3.1) Spotbug가 경고를 발생시키는 방법은 없습니다. 아마도 checkerframework가 그렇게 할 수 있습니다.

안타깝게도 이러한 주석은 임의의 호출 사이트가있는 라이브러리의 공용 메소드와 각 호출 사이트를 알 수있는 비 공용 메소드의 경우를 구별하지 않습니다. 따라서 단일 선언에서는 "널 (null)이 바람직하지 않지만 널 (null)을 전달할 준비를한다"는 이중 의미는 불가능하므로 위 예제는 인터페이스와 구현에 대해 서로 다른 주석을 가지고 있습니다.

분할 인터페이스 방식이 실용적이지 않은 경우 다음 방식이 타협됩니다.

        public Person createPerson(
                @NonNull String firstname,
                @NonNull String lastname
                ) {
            // even though parameters annotated as NonNull, library clients might call with null.
            if (firstname == null) throw new IllagalArgumentException(...);
            if (lastname == null) throw new IllagalArgumentException(...);
            return doCreatePerson(fistname, lastname, nickname);
        }

이렇게하면 클라이언트가 유용한 오류를 반환하는 동안 null을 전달하지 않고 (올바른 코드 작성) 도움이됩니다.


이 답변은 지금 만 찾았지만 @tkruse에서 "Eclipse jdt 주석은 정적 메서드 반환 및 기타 경우에는 적용 할 수 없습니다." (첫 번째 부분은 사실이 아니며 두 번째 부분은 모호합니다 :)).
— Stephan Herrmann

@StephanHerrmann : 기억이 없습니다. 글 머리 기호를 제거했습니다.
— tkruse

12

Eclipse에는 자체 주석이 있습니다.

org.eclipse.jdt.annotation.NonNull

자세한 내용은 http://wiki.eclipse.org/JDT_Core/Null_Analysis 를 참조하십시오.


이것이 Eclipse 3.8 (Juno)에서 통합되어 Eclipse와 IntelliJ를 인라인으로 가져올 것 같습니다. 또한 고유 한 Null 주석 (예 : javax.annotation.Nonnull)을 구성 할 수 있어야하며 NotNull을 기본값으로 설정하는 옵션이 있습니다.
— Motti Strom 2016 년

11

Java Validation API ( javax.validation.constraints.*)에는 @Nullable주석 이 포함되어 있지 않으므로 정적 분석 컨텍스트에서 매우 중요합니다. Java의 기본이 아닌 필드의 기본값이므로 런타임 Bean 유효성 검사에 적합합니다 (즉 유효성 검사 / 강제 대상 없음). 언급 된 목적을 위해 대안에 대한 무게를 측정해야합니다.


7

불행히도, JSR 308이 프로젝트 로컬 Not Null 제안보다 더 많은 값을 추가하지 않을 것입니다.

Java 8단일 기본 주석 또는 자체 Checker프레임 워크 가 제공되지 않습니다 . Find-bugs 또는와 유사 JSR 305하게이 JSR은 대부분의 학술 팀에서 관리가 잘되지 않습니다.

그 뒤에는 상업적 힘이 없기 때문에 NOW (Early Draft Review at NOW) JSR 308가 시작 되지만 6 개월 이내에 배송 될 예정입니다 .-O btw 와 유사합니다 . 그러나 Java 플랫폼에 대한 피해를 최소화하기 위해 창립자로부터 멀리 떨어진 것을 담당했습니다.EDR 3JCPJava 8310308 Oracle

뒤에서 것과 같은 모든 프로젝트, 공급 업체 및 학술 클래스 Checker Framework와는 JSR 308독자적인 검사 주석을 생성합니다.

몇 가지 대중적인 타협이 발견 될 수 있고 Java 9또는에 추가 되거나 또는 ;-) 10와 같은 프레임 워크를 통해 소스 코드가 호환되지 않게 됨Apache CommonsGoogle Guava


7

기계적 인조 인간

이 답변은 Android 전용입니다. 안드로이드는라는 패키지를 지원합니다 support-annotations. 이 제공하는 수십 가지 의 안드로이드 특정의 주석을 또한 제공합니다 일반적인 사람 처럼 NonNull, Nullable등

추가 지원 - 주석 패키지를, 당신의 build.gradle에 다음 종속성을 추가 :

compile 'com.android.support:support-annotations:23.1.1'

다음을 사용하십시오.

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

5

이것을 업스트림 (Java 8?)으로 정렬하기를 기다리는 동안 자신의 프로젝트 로컬 @NotNull및 @Nullable주석을 정의 할 수도 있습니다 . 기본적으로 javax.validation.constraints 사용할 수없는 Java SE로 작업하는 경우에도 유용 할 수 있습니다 .

import java.lang.annotation.*;

/**
 * Designates that a field, return value, argument, or variable is
 * guaranteed to be non-null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface NotNull {}

/**
 * Designates that a field, return value, argument, or variable may be null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface Nullable {}

위의 내용은 이러한 주석의 정적 분석에 대한 지원을 추가하지 않기 때문에 분명히 장식 또는 미래 보장 목적으로 사용됩니다.


4

안드로이드를 위해 개발하고 있다면, 당신은 독자적인 주석을 가진 이클립스 (편집 : 더 이상은 쓸 수 없다)에 다소 묶여있다. Eclipse 3.8+ (Juno)에 포함되어 있지만 기본적으로 비활성화되어 있습니다.

환경 설정> Java> 컴파일러> 오류 / 경고> 널 분석 (하단의 축소 가능 섹션)에서이를 사용할 수 있습니다.

"주석 기반 널 분석 사용"확인

http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage 에는 설정에 대한 권장 사항이 있습니다. 그러나 작업 공간에 외부 프로젝트 (예 : 페이스 북 SDK)가있는 경우 해당 권장 사항을 만족하지 않을 수 있으며 각 SDK 업데이트로 수정하지 않을 수도 있습니다. ;-)

나는 사용한다:

  1. 널 포인터 액세스 : 오류
  2. 널 스펙 위반 : 오류 (포인트 # 1에 링크 됨)
  3. 잠재적 인 널 포인터 액세스 : 경고 (그렇지 않으면 페이스 북 SDK에 경고가 있음)
  4. 널 어노테이션과 널 유추의 충돌 : 경고 (포인트 # 3에 링크 됨)

4
이클립스에 묶여? 사실이 아니다.
— dcow

1
안드로이드 개발을 지원하는 @DavidCowden IntelliJ IDEA는 안드로이드 스튜디오가 소개되기 몇 시간 전에 가능했다고 생각합니다.
— Mārtiņš Briedis

@ MārtiņšBriedis 네, 맞습니다. 나는 당신이 의미하는 것 같아요 @chaqke.
— dcow

android와 intellij에는 별도의 주석이 있으며 Java에 공식 주석이 포함될 때까지 그대로 유지됩니다. 이클립스와 함께 이클립스 주석을 사용하기위한 지침입니다.
— chaqke

이클립스에 묶인 적이 없다. 원하는 IDE를 사용할 수 있습니다.
— DennisK

4

큰 프로젝트를 수행하는 경우 더 잘 만드는 것이 좋습니다 자신 만의 주석 @Nullable및 / 또는 @NotNull주석 .

예를 들면 다음과 같습니다.

@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD,
                              java.lang.annotation.ElementType.METHOD,    
                              java.lang.annotation.ElementType.PARAMETER,
                              java.lang.annotation.ElementType.LOCAL_VARIABLE})
public @interface Nullable 
{
}

올바른 보존 정책 을 사용하는 경우 주석 런타임에 을 사용할 수 없습니다 . 그 관점에서 볼 때 그것은 단지 내부 것입니다.

이것이 엄격한 과학은 아니지만 사용하는 것이 가장 합리적이라고 생각합니다. 내부 클래스 합니다.

  • 내부적 인 것입니다. (기능적 또는 기술적 영향 없음)
  • 많은 많은 사용법으로.
  • IntelliJ와 같은 IDE는 사용자 정의 @Nullable/@NotNull 주석을 합니다.
  • 대부분의 프레임 워크는 자체 내부 버전도 선호합니다.

추가 질문 (의견 참조) :

IntelliJ에서 이것을 구성하는 방법은 무엇입니까?

IntelliJ 상태 표시 줄의 오른쪽 하단에있는 "경찰관"을 클릭하십시오. 팝업에서 "검사 구성"을 클릭하십시오. 다음 ... 주석 구성


1
나는 당신의 조언을했지만, idea에 대해 아무것도 말할 void test(@NonNull String s) {}호출test(null);
— user1244932

3
@ user1244932 IntelliJ IDEA을 의미합니까? 정적 분석에 사용하는 Null 허용 주석을 구성 할 수 있습니다. 정확히 어디에 있는지 모르지만 정의 할 수있는 곳은 "파일> 설정> 빌드, 실행, 배포> 컴파일러"에 있으며 "주석 구성 ..."버튼이 있습니다.
— Adowrath

@ user1244932 아직도 찾고 있다면 스크린 샷을 참조하십시오.
— bvdb

3

여기에 이미 답변이 너무 많지만 (a) 2019 년이며 여전히 "표준"이 없습니다. Nullable 없으며 (b) Kotlin에 대한 다른 답변은 없습니다.

Kotlin은 Java와 100 % 상호 운용 가능하며 핵심 Null 안전 기능이 있기 때문에 Kotlin에 대한 참조가 중요합니다. Java 라이브러리를 호출 할 때 이러한 주석을 활용하여 Kotlin 도구에 Java API가 수락 또는 리턴 할 수 있는지 알 수 있습니다 null.

내가 아는 Nullable한 Kotlin org.jetbrains.annotations과 호환되는 유일한 패키지는 및 android.support.annotation(현재 androidx.annotation)입니다. 후자는 Android 와만 호환되므로 Android 이외의 JVM / Java / Kotlin 프로젝트에서는 사용할 수 없습니다. 그러나 JetBrains 패키지는 모든 곳에서 작동합니다.

따라서 Android 및 Kotlin에서도 작동하고 Android Studio 및 IntelliJ에서 지원되는 Java 패키지를 개발하는 경우 JetBrains 패키지를 선택하는 것이 가장 좋습니다.

메이븐 :

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations-java5</artifactId>
    <version>15.0</version>
</dependency>

그레들 :

implementation 'org.jetbrains:annotations-java5:15.0'

2
흠, 그렇지 않으면 말한다 : kotlinlang.org/docs/reference/…
— skagedal

3

Java 8 에서이 작업을 수행하는 다른 방법이 있습니다. 필요한 작업을 수행하기 위해 두 가지 작업을 수행하고 있습니다.

  1. 널 입력 가능 필드를 랩핑하여 유형으로 널 입력 가능 필드를 명시 적으로 작성 java.util.Optional
  2. 구성 할 때 null이 아닌 모든 필드가 null이 아닌지 확인 java.util.Objects.requireNonNull

예:

import static java.util.Objects.requireNonNull;

public class Role {

  private final UUID guid;
  private final String domain;
  private final String name;
  private final Optional<String> description;

  public Role(UUID guid, String domain, String name, Optional<String> description) {
    this.guid = requireNonNull(guid);
    this.domain = requireNonNull(domain);
    this.name = requireNonNull(name);
    this.description = requireNonNull(description);
  }

내 질문은, Java 8을 사용할 때 주석을 달아야합니까?

편집 : 나중에 일부 Optional는 인수 에 사용하는 나쁜 습관을 고려한다는 것을 알았습니다. 여기에 장단점에 대한 좋은 토론이 있습니다. 왜 Java 8의 Optional을 인수에 사용하지 않아야합니까?

인수에 Optional을 사용하지 않는 다른 옵션은 2 개의 생성자가 필요합니다.

  //Non null description
  public Role(UUID guid, String domain, String name, String description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);

        // description will never be null
        requireNonNull(description);

        // but wrapped with an Optional
        this.description = Optional.of(description);
      }

  // Null description is assigned to Optional.empty
  public Role(UUID guid, String domain, String name) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = Optional.empty();
      }

정적 분석 검사자가 널이 아니어야한다는 의도를 알 수 있도록 4 개의 공식 매개 변수 모두에 @NotNull 주석이 여전히 필요하다고 말하고 싶습니다. Java 언어에는 아직 그것을 집행하는 것이 없습니다. 또한 방어 적으로 프로그래밍하는 경우 설명이 null이 아닌지 확인해야합니다.
— jaxzin

2
여전히이 코드를 작성할 수 있습니다 : new Role(null,null,null,null);. 주석을 사용하면 IDE 및 정적 분석에서 null을 해당 매개 변수로 전달할 수 없음을 경고합니다. 그것이 없으면 코드를 실행할 때까지 찾지 못합니다. 이것이 주석의 가치입니다.
— jaxzin

2
또한 개발자가 상호 배타적이지 않은 IDE 또는 텍스트 편집기를 원하는 환경에서 사용할 수 있습니다. 그런 다음 maven-pmd-plugin 및 / 또는 SonarQube를 빌드 프로세스에 통합하여 풀 요청과 같이 미리 병합 된 코드 품질 문제를 권장하고 강조하며 심지어 게이트합니다.
— jaxzin 2016 년

2
선택 사항은 메소드 인수 또는 개인 필드로 사용되지 않습니다. 예를 참조하십시오 stuartmarks.wordpress.com/2016/09/27/vjug24-session-on-optional
— assylias

1
@assylias 그렇습니다. 나중에 그들은 우리에게 아무것도 사지 않기 때문에 권장하지 않는다고 말했으며, 그들의 합리성을 확실히 이해할 수 있습니다. 이 경우에는 여기에 인수 description 를 null로 만들 수 없으며 클라이언트 코드는 빈 문자열을 전달할 수 있지만 많은 경우 빈 문자열을 구별하고 값을 갖지 않는 것이 편리합니다. 귀하의 의견에 감사드립니다. 답변을 업데이트하겠습니다.
— Mozart Brocchini

2

태양은 이제 자신의 것이 없습니까? 이것은 무엇입니까 :
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-com.sun/istack/com.sun.istack.internal.htm

이것은 지난 몇 년 동안 사용한 모든 Java 버전과 함께 패키지 된 것 같습니다.

편집 : 아래 주석에서 언급했듯이 이러한 주석을 사용하고 싶지 않을 것입니다. 이 경우 IntelliJ jetbrains 주석에 투표합니다.


10
나는 그것이 무엇인지 모른다. 그러나 패키지 이름은 일반적인 용도가 아닌 큰 힌트가되어야한다.
— Stephen C

3
일반적으로 com.sun 네임 스페이스의 클래스는 내부적으로 사용하지 않습니다. 직접적인 사용을위한 것이 아닙니다. 장래의 가용성 또는 동작에 대해 보장하지 않습니다. com.sun 아티팩트를 직접 사용하려면 실제로 견고한 케이스가 있어야합니다.
— luis.espinal

게다가 Java2s.com에서 열악한 HTML 형식으로 표시되는 내용은 붉은 깃발을
— 보여줄 것입니다

2

IntelliJ의 장점 중 하나는 주석을 사용할 필요가 없다는 것입니다. 직접 작성하거나 원하는 다른 도구를 사용할 수 있습니다. 단일 유형으로 제한되지도 않습니다. 다른 @NotNull 주석을 사용하는 두 개의 라이브러리를 사용하는 경우 IntelliJ에 두 라이브러리를 모두 사용하도록 지시 할 수 있습니다. 이렇게하려면 "검사 구성"으로 이동하여 "일정한 조건 및 예외"검사를 클릭 한 다음 "검사 구성"버튼을 누르십시오. 가능한 경우 Nullness Checker를 사용하므로 해당 주석을 사용하도록 IntelliJ를 설정했지만 원하는 다른 도구와 함께 작동하도록 할 수 있습니다. (수년 동안 IntelliJ의 검사를 사용해 왔기 때문에 다른 도구에 대해서는 의견이 없으며 그 도구를 좋아합니다.)


1

또 다른 옵션은 ANTLR 4와 함께 제공되는 주석입니다. Pull Request # 434 에 따라 @NotNull및 @Nullable주석을 포함하는 아티팩트 에는 이러한 속성 중 하나가 잘못 사용될 경우 컴파일 시간 오류 및 / 또는 경고를 생성하는 주석 프로세서가 포함됩니다 (예 : 둘 다 동일한 항목에 @Nullable적용 되거나 기본 유형의 항목에 적용되는 경우 ). 어노테이션 프로세서는 소프트웨어 개발 프로세스 중에 메소드 상속의 경우를 포함하여 이러한 어노테이션의 적용으로 전달되는 정보가 정확하다는 추가 보증을 제공합니다.


1

Spring Framework를 사용하여 애플리케이션을 빌드하는 경우 Beans Validation 에서 다음과 같은 패키지로 제공되는 javax.validation.constraints.NotNullcomming을 사용하는 것이 좋습니다 .

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>

이 주석의 주요 장점은 Spring이 메소드 매개 변수와 클래스 필드를 모두 지원한다는 점이다 javax.validation.constraints.NotNull. 지원을 활성화하려면 다음을 수행하십시오.

  1. jsr-303 / jsr-349 주석의 유효성 검사기 (Hibernate Validator 5.x 종속성과 함께 제공됨)를 구현하여 Bean 유효성 검증을위한 api jar 및 jar을 제공하십시오.

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
  2. Spring의 컨텍스트에 MethodValidationPostProcessor 제공

      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {
    
            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
  3. 마지막으로 Spring에 클래스에 주석을 달면 org.springframework.validation.annotation.Validated유효성 검사가 Spring에 의해 자동으로 처리됩니다.

예:

@Service
@Validated
public class MyServiceImpl implements MyService {

  @Override
  public Something doSomething(@NotNull String myParameter) {
        // No need to do something like assert myParameter != null  
  }
}

doSomething 메소드를 호출하고 매개 변수 값으로 null을 전달하면 spring (HibernateValidator를 사용하여)이 발생합니다. ConstraintViolationException 합니다. 여기서 수동 작업이 필요하지 않습니다.

반환 값의 유효성을 검사 할 수도 있습니다.

또 다른 중요한 장점 javax.validation.constraints.NotNullBeans Validation Framework에 오는 은 현재 개발되어 현재 버전 2.0에 대한 새로운 기능이 계획되어 있다는 것입니다.

무엇에 대해 @Nullable? Beans Validation 1.1에는 그런 것이 없습니다. 글쎄, 당신이 주석을 달지 @NotNull않은 모든 것보다 @NonNull효과적으로 사용하기로 결정했다면 , @Nullable주석은 쓸모가 없다고 주장 할 수 있다.


1
사용하지 마십시오. 정적 코드 분석이 아닌 런타임 유효성 검사에 사용됩니다. 자세한 내용은 justsomejavaguy.blogspot.com/2011/08/… 를 참조하십시오. 출처 : @ luis.espinal의 219 표로 답변이 삭제되었습니다.
— koppor

@koppor : 동의하지 않습니다. 이것이 사용법이 아니라면 Spring이 런타임에 그것을 처리하는 이유는 무엇입니까? 또한 Beans 유효성 검증 프레임 워크는 런타임시 컨텍스트 오브젝트 (현재 어노테이션이 있거나 유효성이 검증 된 인스턴스)에 액세스 할 수 있으므로 런타임 분석을 위해 주석을 작성할 수 있습니다.
— walkeros

0

Spring 5에는 패키지 수준에서 @NonNullApi가 있습니다. 이것은 이미 Spring 의존성이있는 프로젝트에 편리한 선택처럼 보입니다. 모든 필드, 매개 변수 및 반환 값의 기본값은 @NonNull 및 @Nullable이 다른 몇 군데에 적용될 수 있습니다.

package-info.java 파일 :

@org.springframework.lang.NonNullApi
package com.acme;

https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.nullability.annotations

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.