代码对比
✕ 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,只有可空异常需要标注。
供应商中立
JSpecify 是跨框架的标准,不绑定于 Spring 特定注解。
工具集成
IDE、分析器和 Kotlin 能够更好地理解 JSpecify 注解。
旧方式
Spring @NonNull/@Nullable
现代方式
JSpecify @NullMarked
自 JDK
17
难度
中级
JDK 支持
Spring Null 安全与 JSpecify
可用
自 Spring Framework 7.0 起可用(需要 Java 17+)
工作原理
Spring 5 和 6 在 org.springframework.lang 包中引入了自己的 null 安全注解。Spring 7 迁移到 JSpecify,使非 null 成为模块级默认值——只有可空的例外需要注解。
相关文档