Spring Null-Safetyアノテーション

1概要

Spring 5以降、より安全なコードを書くのに役立つ興味深い機能にアクセスできるようになりました。この機能はnull-safeと呼ばれ、潜在的なnull参照を監視する保護手段のように機能する一連の注釈です。

安全でないコードを回避するのではなく、コンパイル時にnull-safe機能によって警告が生成されます。

2 @ NonNull アノテーション

@ NonNull アノテーションは、null-safe機能のすべてのアノテーションの中で最も重要です。 ** このアノテーションは、オブジェクト参照が予想される場所であればどこでも、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-safe機能により、ツールはそのような危険性を報告できます。

たとえば、IntelliJ IDEAでコードを記述し、 fullName フィールドを @ NonNull アノテーションで装飾すると、警告が表示されます。

この表示のおかげで、Googleでは問題を事前に認識しており、ランタイムエラーを回避するために適切な措置を講じることができます。

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;

以前見た警告は消えました。

この状況では、** フィールド上の @ NonNullFields のセマンティクスを上書きするために @ Nullable アノテーションを使用しました。

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-safeは、NPEの可能性を減らすのに役立つ優れた機能です。ただし、この機能を使用する際に注意が必要な点が2つあります。

  • IntelliJなどの補助的な開発ツールでのみ使用可能

アイディア ** 実行時に null チェックを強制するものではありません。

NPEを避けるために自分自身をコーディングする

このチュートリアルのソースコードは、https://github.com/eugenp/tutorials/tree/master/spring-all[GitHubで利用可能]にあります。