SpringのNull安全性とJSpecify
Spring 7がJSpecifyアノテーションを採用し、非nullをデフォルトにしてアノテーションの冗長さを削減する。
コード比較
✕ Spring 5/6
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
public class UserService {
@Nullable
public User findById(@NonNull String id) {
return repository.findById(id).orElse(null);
}
@NonNull
public List<User> findAll() {
return repository.findAll();
}
@NonNull
public User save(@NonNull User user) {
return repository.save(user);
}
}
✓ Spring 7
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public class UserService {
public @Nullable User findById(String id) {
return repository.findById(id).orElse(null);
}
public List<User> findAll() {
return repository.findAll();
}
public User save(User user) {
return repository.save(user);
}
}
このコードに問題がありますか? お知らせください。
モダンな方法が優れている理由
非nullがデフォルト
@NullMarkedにより未アノテートの型は非nullになるため、nullになりうる例外だけにアノテーションが必要です。
エコシステム標準
JSpecifyアノテーションはNullAway・Error Prone・IDEに認識されるクロスフレームワーク標準です。
豊かなツールサポート
最新の静的解析ツールがJSpecifyのnullモデルを理解し、コンパイル時に違反を報告します。
旧来のアプローチ
Spring @NonNull/@Nullable
モダンなアプローチ
JSpecify @NullMarked
JDKバージョン
17
難易度
中級
JDKサポート
SpringのNull安全性とJSpecify
利用可能
Spring Framework 7.0(Java 17以上が必要)以降、利用可能
仕組み
Spring 5と6はorg.springframework.langパッケージに独自のnull安全アノテーションを導入しました。便利でしたが、フレームワーク固有であり非nullの要素すべてに明示的なアノテーションが必要でした。Spring 7はクロスエコシステム標準であるJSpecifyに移行しました。クラスまたはパッケージレベルの@NullMarkedアノテーションにより、すべての未アノテートの型がデフォルトで非nullになります。実際にnullになりうる型だけ@Nullableアノテーションが必要となり、冗長さが大幅に削減されます。JSpecifyアノテーションはNullAway・Error Prone・IntelliJ IDEAなどの主要な静的解析ツールに認識され、Spring固有アノテーションより豊かなツールサポートをもたらします。
関連ドキュメント