어떤 @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. 다른 패키지를 졸업대로 javaxjava과거의 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/14731https://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.