1. 概要

Spring 5以降、より安全なコードを作成するのに役立つ興味深い機能にアクセスできるようになりました。 この機能はnull-safetyと呼ばれ、潜在的なnull参照を監視するセーフガードのように機能するアノテーションのグループです。

安全でないコードを回避するのではなく、 null-safety機能はコンパイル時に警告を生成します。このような警告は、実行時に壊滅的なnullポインター例外(NPE)を防ぐ可能性があります。

2. @NonNullアノテーション

@NonNull アノテーションは、null-safety機能のすべてのアノテーションの中で最も重要です。 このアノテーションt0は、オブジェクト参照が期待される場所であればどこでもnull以外の制約を宣言できます:フィールド、メソッドパラメーター、またはメソッドの戻り値。

Personという名前のクラスがあるとします。

public class Person {
    private String fullName;

    void setFullName(String fullName) {
        if (fullName != null && fullName.isEmpty()) {
            fullName = null;
        }
        this.fullName = fullName;
    }

    // getter
}

このクラス定義は有効ですが、欠陥があります– fullNameフィールドがnullに設定されている可能性があります。 これが発生した場合、fullNameを操作するときにNPEが発生する可能性があります。

Spring null-safety機能により、ツールはそのような危険を報告できます。 たとえば、IntelliJ IDEAでコードを記述し、fullNameフィールドを@NonNullアノテーションで装飾すると、次の警告が表示されます。

この指示のおかげで、問題を事前に認識し、実行時の障害を回避するための適切なアクションを実行できます。

3. @NonNullFieldsアノテーション

@NonNull アノテーションは、nullの安全性を保証するのに役立ちます。 ただし、null以外のすべてのフィールドをこのアノテーションで装飾すると、コードベース全体が汚染されます。

@NonNull を別のアノテーション、@NonNullFieldsで悪用することを回避できます。 このアノテーションはパッケージレベルで適用可能であり、アノテーション付きパッケージのすべてのフィールドがデフォルトでnullではないことを開発ツールに通知します。

@NonNullFields アノテーションを開始するには、パッケージのルートディレクトリに package-info.java という名前のファイルを作成し、パッケージに@NonNullFieldsアノテーションを付ける必要があります。

@NonNullFields
package org.baeldung.nullibility;

Person クラスで、nickNameという別のプロパティを宣言しましょう。

package org.baeldung.nullibility;

// import statements

public class Person {
    private String nickName;

    void setNickName(@Nullable String nickName) {
        if (nickName != null && nickName.isEmpty()) {
            nickName = null;
        }
        this.nickName = nickName;
    }

    // other declarations
}

今回は、nickNameフィールドを@NonNullで装飾しませんが、同様の警告が表示されます。

@NonNullFields アノテーションは、 @NonNull が提供するのと同じレベルの安全性を確保しながら、コードの冗長性を減らします。

4. @Nullableアノテーション

@NonNullFields アノテーションは、ボイラープレートを減らすのに役立つため、@NonNullよりも一般的に推奨されます。 パッケージレベルで指定されたnull以外の制約から一部のフィールドを除外したい場合があります。

nickNameフィールドに戻り、@Nullableアノテーションで装飾してみましょう。

@Nullable
private String nickName;

以前に見た警告はなくなりました。

この状況では、 @Nullableアノテーションを使用して、フィールド上の@NonNullFieldsのセマンティクスをオーバーライドしました。

5. @NonNullApiアノテーション

@NonNullFields アノテーションは、その名前が示すように、フィールドにのみ適用されます。 メソッドのパラメーターと戻り値に同じ影響を与えるには、@NonNullApiが必要です。

@NonNullFields と同様に、package-info.javaファイルで@NonNullApiアノテーションを指定する必要があります。

@NonNullApi
package org.baeldung.nullibility;

nickNameフィールドのゲッターを定義しましょう。

package org.baeldung.nullibility;

// import statements

public class Person {
    @Nullable
    private String nickName;

    String getNickName() {
        return nickName;
    }

    // other declarations
}

@NonNullApi アノテーションが有効な場合、getNickNameメソッドによって生成される可能性のあるnull値について警告が発行されます。

@NonNullFields アノテーションと同様に、メソッドレベルで@NonNullApi@Nullableアノテーションでオーバーライドできることに注意してください。

6. 結論

Spring null-safetyは、NPEの可能性を減らすのに役立つ優れた機能です。 ただし、この機能を使用する際に注意する必要がある2つの重要なポイントがあります。

  • IntelliJIDEAなどのサポート開発ツールでのみ使用できます
  • 実行時にnullチェックを強制しません。それでも、NPEを回避するために自分でコードを作成する必要があります。

このチュートリアルのソースコードは、GitHubにあります。