注解 @NotEmpty 和 @NotNull区别

一:

@NotEmpty@NotNull 是 Java 中用于数据校验的注解,它们都来自 Jakarta Bean Validation 框架(之前称为 Hibernate Validator),但适用场景和约束强度有所不同。

1. @NotNull

  • 作用:验证目标字段不能为 null,但允许为空值(如空字符串 ""、空集合 [] 等)。
  • 适用类型:所有引用类型(包括字符串、集合、数组等)。
  • 示例
    public class User {
        @NotNull
        private String name; // name 不能为 null,但可以是空字符串 ""
    }
    

2. @NotEmpty

  • 作用:验证目标字段既不能为 null,也不能是空值。具体规则:
    • 字符串:长度必须大于 0(即不能为 "")。
    • 集合/数组:元素数量必须大于 0(即不能为 [])。
    • Map:键值对数量必须大于 0。
  • 适用类型:字符串、集合、数组、Map 等。
  • 示例
    public class User {
        @NotEmpty
        private String name; // name 不能为 null 或 ""
        
        @NotEmpty
        private List<String> hobbies; // hobbies 不能为 null 或空列表 []
    }
    

3. 核心区别

注解 允许 null 允许空值(如 "", [] 示例(假设字段被注解)
@NotNull ❌ 不允许 ✅ 允许 name = "" 合法
@NotEmpty ❌ 不允许 ❌ 不允许 name = "" 非法

4. 依赖引入

若使用 Spring Boot,需添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

5. 常见误区

  • @NotEmpty 与字符串空格@NotEmpty 不校验空格,例如 " " 是合法的。若需同时校验空格,需搭配 @NotBlank
  • 基本数据类型@NotNull 不适用基本数据类型(如 int, long),因为它们无法赋值为 null

总结

  • @NotNull:仅保证字段不为 null,适用于允许空值但需避免 null 的场景。
  • @NotEmpty:更强的约束,适用于必须同时保证非 null 和非空值的场景(如表单必填项)。

二:

对于 List<String> data 字段,应优先使用 @NotEmpty,原因如下:

1. 功能差异

  • @NotNull:仅确保 data 不为 null,但允许空列表(data = [])。
  • @NotEmpty:确保 data 既不为 null,也不为空列表(data.size() > 0)。

示例

public class Request {
    @NotEmpty(message = "数据不能为空")
    private List<String> data; // 要求列表非 null 且至少包含一个元素
}

2. 应用场景

  • 若允许空列表(如业务逻辑允许空数据):用 @NotNull
  • 若必须包含元素(如表单提交要求至少选一个选项):用 @NotEmpty

3. 推荐选择

实际开发中,@NotEmpty 更常见,因为:

  • 空列表([])通常无业务意义(例如前端未选择任何数据)。
  • @NotEmpty 能同时避免 null 和空列表,减少 NPE 风险。

4. 扩展校验

若需进一步校验列表元素(如字符串不为空),可结合 @Valid 和元素级注解:

public class Request {
    @NotEmpty(message = "数据不能为空")
    private List<@NotBlank String> data; // 列表非空,且每个元素非空字符串
}

总结

  • @NotEmpty:若要求列表必须包含元素。
  • @NotNull:若允许空列表,但需避免 null