杰瑞科技汇

Java对象如何判断为空?

判断对象是否为 null (最基本)

这是最基础也是最常见的一步,如果一个变量没有被赋值(即没有指向任何内存地址),那么它的值就是 null

Java对象如何判断为空?-图1
(图片来源网络,侵删)

场景: 检查一个对象引用是否存在。

public class Main {
    public static void main(String[] args) {
        String str1 = null;
        String str2 = "hello";
        // 使用 == 操作符判断
        if (str1 == null) {
            System.out.println("str1 是 null"); // 会执行
        }
        if (str2 == null) {
            System.out.println("str2 是 null"); // 不会执行
        }
        // 最佳实践:总是将 null 放在 == 的左边
        // if (null == str1) { ... } // 这样可以避免手误写成 if (str1 = null) ...
    }
}

要点:

  • 用于比较两个对象的引用地址是否相等。
  • 对于所有对象,null 都是一个关键字,表示“空引用”。
  • 永远不要对一个 null 对象调用任何方法或访问任何字段,否则会抛出 NullPointerException(空指针异常)。

判断字符串是否为“空” (String 特有)

对于 String 对象,null 和 “空字符串” () 是不同的概念。

  • null:表示 String 对象本身不存在。
  • 表示 String 对象存在,但它不包含任何字符(长度为 0)。

判断一个字符串是否“为空”,通常需要同时判断 null 和 。

Java对象如何判断为空?-图2
(图片来源网络,侵删)

手动判断 (基础)

String str = null;
if (str == null || str.isEmpty()) {
    System.out.println("字符串为空或为 null"); // 会执行
}
str = "";
if (str == null || str.isEmpty()) {
    System.out.println("字符串为空或为 null"); // 会执行
}
str = " ";
if (str == null || str.isEmpty()) {
    System.out.println("字符串为空或为 null"); // 不会执行
}

说明:

  • str.isEmpty() 方法内部会先检查 str 是否为 null"".isEmpty() 返回 true
  • 但是strnull,直接调用 str.isEmpty() 会抛出 NullPointerException,必须先用 str == null 进行判断。

使用 StringUtils (推荐,来自 Apache Commons Lang 或 Spring)

在实际项目中,我们通常使用工具类来简化这些判断,它们更简洁、更健壮。

Apache Commons Lang: org.apache.commons.lang3.StringUtils

// 添加依赖: org.apache.commons:commons-lang3:3.12.0
import org.apache.commons.lang3.StringUtils;
String str = null;
// isBlank() 同时判断 null, "", "   " (纯空格)
if (StringUtils.isBlank(str)) {
    System.out.println("字符串为 null、空或仅包含空白字符"); // 会执行
}
str = "   ";
if (StringUtils.isBlank(str)) {
    System.out.println("字符串为 null、空或仅包含空白字符"); // 会执行
}
// isEmpty() 只判断 null 和 ""
if (StringUtils.isEmpty(str)) {
    System.out.println("字符串为 null 或空"); // 不会执行,因为 str 是 "   "
}

常用方法:

  • StringUtils.isEmpty(CharSequence cs): 判断是否为 null 或 。
  • StringUtils.isBlank(CharSequence cs): 判断是否为 null、 或只包含空白字符(如 \t\n\r\f),这是最常用的方法,因为它能处理用户输入中常见的“全是空格”的情况。

Spring Framework: org.springframework.util.StringUtils

如果你已经在使用 Spring,可以直接使用其提供的工具类。

// 添加依赖: org.springframework:spring-core:...
import org.springframework.util.StringUtils;
String str = "   ";
if (StringUtils.hasText(str)) {
    System.out.println("字符串不为空且包含非空白字符"); // 不会执行
}
if (StringUtils.hasLength(str)) {
    System.out.println("字符串不为空且长度大于0"); // 会执行
}

常用方法:

  • StringUtils.hasText(String str): 判断是否为 null、空或只包含空白字符,功能和 commons-lang3isBlank 类似。
  • StringUtils.hasLength(String str): 判断是否为 null 或长度为 0,功能和 commons-lang3isEmpty 类似。

判断集合/数组是否为“空”

对于集合(如 List, Set, Map)和数组,判断“空”通常指:

  1. 引用是否为 null
  2. 如果引用不为 null,其内部是否包含任何元素。

手动判断

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
// List 示例
List<String> list = null;
if (list == null || list.isEmpty()) {
    System.out.println("List 为 null 或没有元素"); // 会执行
}
list = new ArrayList<>();
if (list == null || list.isEmpty()) {
    System.out.println("List 为 null 或没有元素"); // 会执行
}
// Map 示例
Map<String, Integer> map = new HashMap<>();
if (map == null || map.isEmpty()) {
    System.out.println("Map 为 null 或没有键值对"); // 会执行
}

使用 Java 8+ Stream API (函数式风格)

对于复杂的判断,Stream API 提供了另一种优雅的方式。

import java.util.Arrays;
import java.util.List;
List<String> list = Arrays.asList("a", "b", null);
// 判断 List 是否为 null 或所有元素都为 null
boolean allNullOrListEmpty = list == null || list.stream().allMatch(Objects::isNull);
System.out.println("List 为 null 或所有元素都为 null: " + allNullOrListEmpty); // false
List<String> emptyList = new ArrayList<>();
boolean isReallyEmpty = emptyList == null || emptyList.stream().allMatch(Objects::isNull);
System.out.println("emptyList 为 null 或所有元素都为 null: " + isReallyEmpty); // true (因为 isEmpty() 为 true)

注意: 对于简单的“是否为空”判断,list.isEmpty() 更直接高效,Stream API 更适合复杂的元素级判断。


判断自定义对象是否为“空”

对于你自己创建的 JavaBean (POJO),"为空"的定义可能更复杂,它可能意味着:

  • 对象本身是 null
  • 对象的所有字段都是 null 或默认值(0, false)。

手动 equals 方法

你可以在你的类中重写 equals 方法来定义“空”的逻辑。

public class User {
    private Long id;
    private String name;
    private Integer age;
    // 构造函数、getters、setters...
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        // 定义 "空" 的逻辑:id 和 name 都为 null
        return (id == null && user.id == null) &&
               (name == null && user.name == null);
    }
    // ... 建议同时重写 hashCode()
}
// 使用
User user1 = new User();
user1.setId(null);
user1.setName(null);
User emptyUser = new User(); // 所有字段都是默认值 null
System.out.println(user1.equals(emptyUser)); // true

缺点: 这种方式会与标准的 equals 语义(对象内容相等)冲突,容易引起混淆。

专门的 isEmpty() 方法 (推荐)

创建一个专门的方法来判断对象是否“业务上为空”,这是更清晰的做法。

public class User {
    private Long id;
    private String name;
    private Integer age;
    // 构造函数、getters、setters...
    /**
     * 判断用户对象是否为空(业务定义)
     */
    public boolean isEmpty() {
        // 业务规则:id 和 name 都为空,则视为空用户
        return this.id == null && (this.name == null || this.name.trim().isEmpty());
    }
}
// 使用
User user = new User();
user.setId(null);
user.setName("  "); // 全是空格
if (user.isEmpty()) {
    System.out.println("这是一个空用户"); // 会执行
}

使用 Lombok @Delegate (高级技巧)

如果你的类是一个简单的数据容器,并且你想委托调用某个内部集合的 isEmpty 方法,可以使用 Lombok。

import lombok.Delegate;
public class ShoppingCart {
    private List<Item> items = new ArrayList<>();
    // @Delegate 会将 List 接口中的所有方法(包括 isEmpty)委托给 items 字段
    @Delegate
    private List<Item> getItems() {
        return items;
    }
}
// 使用
ShoppingCart cart = new ShoppingCart();
System.out.println(cart.isEmpty()); // true,实际调用的是 cart.getItems().isEmpty()

总结与最佳实践

场景 推荐方法 示例
判断对象引用是否为 null if (myObject == null)
判断字符串是否为 null StringUtils.isEmpty() StringUtils.isEmpty(str)
判断字符串是否为 null、或纯空格 StringUtils.isBlank() StringUtils.isBlank(str)
判断集合/数组是否为 null 或无元素 + isEmpty() if (myList == null || myList.isEmpty())
判断自定义对象是否“业务为空” 自定义 isEmpty() 方法 if (user.isEmpty())

核心思想:

  1. 明确“空”的定义:在你写代码之前,先想清楚你判断的“空”到底是什么意思,是引用为空?内容为空?还是业务逻辑上的空?
  2. 防御性编程:始终先检查 null,再调用对象的方法,使用工具类(如 StringUtils)可以极大地减少出错的可能性。
  3. 代码可读性:使用像 StringUtils.isBlank(str) 这样的方法,比写一长串 str == null || str.trim().isEmpty() 更清晰、更不易出错。
分享:
扫描分享到社交APP
上一篇
下一篇