Java 注解@NotNull 和 @NotEmpty区别深度解析

 更新时间:2025年09月26日 09:10:12   作者:还航  
本文给大家介绍了Java注解@NotNull和@NotEmpty区别深度解析,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

要理解这两个 Java 注解的核心区别与应用场景,需从定义来源、校验逻辑、适用类型三个维度展开分析,以下是详细解读:

一、核心信息概览

首先明确两个注解的基础定位,避免混淆:

对比维度

javax.validation.constraints.NotNull

org.hibernate.validator.constraints.NotEmpty

所属框架

JSR 380 标准(Java Validation API)

Hibernate Validator 扩展(标准的实现之一)

核心作用

禁止值为 null

禁止值为 null 禁止 “空内容”(如空字符串、空集合)

依赖关系

标准注解,所有 Validation 实现都支持

需额外引入 Hibernate Validator 依赖

二、关键差异深度解析

1. 校验逻辑:“单一禁止” vs “双重禁止”

这是两者最核心的区别,直接决定了校验范围:

  • @NotNull:仅校验 “是否为 null”

只判断值是否为 null,不关心非 null 值的 “内容是否为空”。

示例(非 null 但 “空内容” 的情况,@NotNull 会判定为有效):

public class User {
// 允许:值为""(空字符串)、[](空集合)、new Object()(非null对象)
@NotNull
private String username = "";
@NotNull
private List<String> tags = new ArrayList<>(); // 空集合也会通过校验
}
  • @NotEmpty:校验 “非 null + 非空内容”

是 @NotNull 的增强版,同时满足两个条件才判定为有效:

public class User {
// 无效:值为null(违反@NotNull)
@NotEmpty
private String username = null;
// 无效:值为""(非null,但空字符串,违反@Size(min=1))
@NotEmpty
private String email = "";
// 无效:值为new ArrayList<>()(非null,但空集合,违反@Size(min=1))
@NotEmpty
private List<String> tags = new ArrayList<>();
}

本质上,@NotEmpty 的校验逻辑是通过组合注解实现的(从源码可见):

// @NotEmpty 源码中组合了 @NotNull 和 @Size(min=1)
@NotNull // 保证非null
@Size(min = 1) // 保证内容长度/大小 ≥1(空内容会触发此注解的校验失败)
public @interface NotEmpty { ... }
    1. 值不能为 null;
    1. 值的 “内容” 不能为空(具体 “空内容” 的定义随类型变化)。

示例(@NotEmpty 判定为无效的情况):

2. 适用数据类型:“通用” vs “限定内容型”

两者适用的字段类型不同,@NotEmpty 仅支持 “有内容长度 / 大小” 的类型:

数据类型

@NotNull 是否适用

@NotEmpty 是否适用

说明(@NotEmpty 的 “空内容” 定义)

基本类型包装类

是(如 Integer)

否(无 “内容” 概念)

如 Integer age = null:@NotNull 校验,@NotEmpty 不支持

String

“空内容”= 长度为 0 的字符串("")

集合 / 数组(如 List、Set、int [])

“空内容”= 长度 / 大小为 0(如 new ArrayList<>()、new int[0])

Map

“空内容”= 键值对数量为 0(new HashMap<>())

自定义对象

是(如 User)

否(无 “内容” 概念)

仅需判断对象是否为 null,用 @NotNull 即可

3. 依赖与兼容性:“标准” vs “扩展”

  • @NotNull:无额外依赖

属于 JSR 380 标准注解(包路径为 javax.validation.constraints),只要项目引入了任何符合标准的 Validation 实现(如 Hibernate Validator、Apache BVal),就能直接使用,兼容性强。

  • @NotEmpty:需依赖 Hibernate Validator

是 Hibernate Validator 提供的扩展注解(包路径为 org.hibernate.validator.constraints),并非标准 API。若项目未引入 Hibernate Validator(仅用标准 API 或其他实现),使用此注解会报 “找不到注解” 错误。

Maven 依赖示例(需手动引入):

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version> <!-- 版本需与项目兼容 -->
</dependency>

三、使用场景选择建议

根据业务需求选择注解,避免 “过度校验” 或 “校验不足”:

业务需求

推荐注解

示例场景

仅需确保值 “存在”(非 null),不关心内容

@NotNull

1. 年龄(Integer age,允许 0 但不允许 null);2. 自定义对象(User user,只要对象非 null 即可)

需确保值 “存在且有意义”(非 null + 非空内容)

@NotEmpty

1. 用户名(String username,不允许 null 或 “”);2. 用户标签(List<String> tags,不允许 null 或空集合);3. 地址(String address,不允许 null 或空字符串)

四、常见误区提醒

  1. 误区 1:@NotNull 能校验空字符串 / 空集合

错误!@NotNull 只管 “是否为 null”,空字符串("")、空集合(new ArrayList<>())都是非 null 值,会通过 @NotNull 校验。

  1. 误区 2:@NotEmpty 能校验基本类型

错误!基本类型(如 int、boolean)无法为 null(默认有初始值,如 int 为 0),且无 “内容” 概念,使用 @NotEmpty 会触发编译错误。

  1. 误区 3:项目中直接用 @NotEmpty 替代 @NotNull

不推荐!@NotEmpty 依赖 Hibernate Validator,若未来切换 Validation 实现(如从 Hibernate Validator 改为 Apache BVal),@NotEmpty 会失效;且部分场景(如基本类型包装类、自定义对象)无需校验 “内容”,用 @NotNull 更轻量。

五、总结

  • 若需标准、通用的 “非 null” 校验,且不依赖具体实现,用 @NotNull;
  • 若需 **“非 null + 非空内容” 的增强校验 **(如字符串、集合),且项目已引入 Hibernate Validator,用 @NotEmpty;
  • 核心原则:“最小必要校验”—— 只校验业务需要的范围,避免冗余。

到此这篇关于Java 注解@NotNull 和 @NotEmpty区别的文章就介绍到这了,更多相关java @NotNull 和 @NotEmpty区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringCloud配置客户端ConfigClient接入服务端

    SpringCloud配置客户端ConfigClient接入服务端

    这篇文章主要为大家介绍了SpringCloud配置客户端ConfigClient接入服务端,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • SpringBoot静态资源的访问方法详细介绍

    SpringBoot静态资源的访问方法详细介绍

    最近在做SpringBoot项目的时候遇到了“白页”问题,通过查资料对SpringBoot访问静态资源做了总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • JAVA设计模式----建造者模式详解

    JAVA设计模式----建造者模式详解

    这篇文章主要为大家详细介绍了java实现建造者模式Builder Pattern,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Java 深拷贝与浅拷贝的分析

    Java 深拷贝与浅拷贝的分析

    本文主要介绍java 的深拷贝和浅拷贝,这里通过实例代码对深拷贝和浅拷贝做了详细的比较,希望能帮到有需要的小伙伴
    2016-07-07
  • MyBatis实现留言板的示例代码

    MyBatis实现留言板的示例代码

    本文主要介绍了MyBatis实现留言板的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 解读@ConfigurationProperties使用时的几个常见误区

    解读@ConfigurationProperties使用时的几个常见误区

    在Spring Boot中,@ConfigurationProperties注解用于绑定配置文件中的属性到Java对象,它支持properties和yml文件格式,并且可以通过prefix属性指定配置属性的前缀,需要注意的是,@PropertySource注解默认只支持properties文件,不支持yml文件
    2024-10-10
  • Java螺旋矩阵处理方法详解

    Java螺旋矩阵处理方法详解

    螺旋矩阵是指一个呈螺旋状的矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环。利用java实现的螺旋矩阵,当输入N之后,会自动打印出螺旋矩阵
    2022-09-09
  • SpringBoot可以同时处理多少请求流程分析

    SpringBoot可以同时处理多少请求流程分析

    SpringBoot默认的内嵌容器是Tomcat,也就是我们的程序实际上是运行在Tomcat里的,所以与其说SpringBoot可以处理多少请求,到不如说Tomcat可以处理多少请求,这篇文章主要介绍了SpringBoot可以同时处理多少请求,需要的朋友可以参考下
    2023-02-02
  • 关于Spring Cloud健康检查的陷阱

    关于Spring Cloud健康检查的陷阱

    这篇文章主要介绍了关于Spring Cloud健康检查的陷阱,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 深入学习java并发包ConcurrentHashMap源码

    深入学习java并发包ConcurrentHashMap源码

    这篇文章主要介绍了深入学习java并发包ConcurrentHashMap源码,整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。,需要的朋友可以参考下
    2019-06-06

最新评论