空指针异常确实是 Java 开发中最常见的 bug 之一。很多开发者习惯性地使用 != null来判断,虽然能解决问题,但会导致代码冗余和可读性下降。下面介绍几种更优雅的处理方式。

一、根据数据类型选择合适工具类

1. 字符串类型:使用 StringUtils

String str = "";
boolean isEmpty = StringUtils.isEmpty(str);  // true

StringUtils.isEmpty() 方法同时检查 null 和空字符串,更加全面。

2. 对象和集合:使用 ObjectUtils

// 对象
Object obj = null;
ObjectUtils.isEmpty(obj); // true

// Map
Map<String,Object> map = Collections.emptyMap();
ObjectUtils.isEmpty(map); // true

// List
List<Integer> list = Collections.EMPTY_LIST;
ObjectUtils.isEmpty(list); // true

// 数组
Object[] objArr = null;
ObjectUtils.isEmpty(objArr); // true

 

3. 集合专用:CollectionUtils 

// List 集合
List<Integer> list = null;
CollectionUtils.isEmpty(list); // true

// Map 集合
Map<String,Object> map = null;
CollectionUtils.isEmpty(map); // true

 

二、ObjectUtils.isEmpty() 源码解析

该方法的强大之处在于它能处理多种数据类型: 

public static boolean isEmpty(@Nullable Object obj) {
    // 判断obj是否为null,如果是直接f
    if (obj == null) {
      returntrue;
    }
    // 判断obj是否是Optional的子类
    if (obj instanceof Optional) {
      // 如果是,则调用isPresent方法判断是否为null
      return !((Optional) obj).isPresent();
    }
    // 判断obj是否是CharSequence的子类
    if (obj instanceof CharSequence) {
      // 如果是,则获取长度,长度等于0时,就认为这个obj是空字符串
      return ((CharSequence) obj).length() == 0;
    }
    // 判断obj是否为数组
    if (obj.getClass().isArray()) {
      // 数组的长度等于0就认为这个数组是空数组
      return Array.getLength(obj) == 0;
    }
    // 判断obj是否为Collection集合的子类
    if (obj instanceof Collection) {
      // 用Collection子类的isEmpty方法判断集合是否为空
      return ((Collection) obj).isEmpty();
    }
    // 判断obj是否为Map接口的子类
    if (obj instanceof Map) {
      // 如果是,则进行强转,并用子类的isEmpty方法判断集合是否为空
      return ((Map) obj).isEmpty();
    }

    // else
    returnfalse;
}

三、特殊场景处理

1. 集合元素全为 null 的判断 

List<Integer> list = Collections.singletonList(null);
boolean allNull = Arrays.stream(list.toArray()).allMatch(ObjectUtils::isEmpty);

 

2. 对象数组的特殊处理 

public static boolean isEmpty(@Nullable Object[] array) {
    return array == null || array.length == 0;
}

 

四、最佳实践总结

  1. 字符串判断:优先使用 StringUtils.isEmpty()

  2. 通用对象判断:使用 ObjectUtils.isEmpty()

  3. 集合专用判断:使用 CollectionUtils.isEmpty()

  4. 复杂场景:对集合元素进行遍历判断

五、预防优于治疗

除了事后判断,更推荐以下预防措施:

  1. 使用 Optional​ 包装可能为 null 的值

  2. 采用注解:如 @Nullable@NonNull

  3. 遵循约定:方法明确返回空集合而非 null

  4. 代码审查:在团队中建立空指针预防规范

通过合理使用工具类和编码规范,可以显著减少空指针异常,让代码更加简洁优雅。记住,好的代码不是没有判断,而是让判断变得无形。

posted on 2025-11-17 10:56  Cetl  阅读(0)  评论(0)    收藏  举报