news 2026/9/1 22:27:13

UtilEmpty空值检查工具类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UtilEmpty空值检查工具类

* 提供高效、标准的空值检查功能。
* 支持 POJO 对象的递归字段检查(作为最后优先级。

import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; /** * 空值检查工具类 * <p> * 提供高效、标准的空值检查功能。 * 支持 POJO 对象的递归字段检查(作为最后优先级),并针对 JDK 内置对象进行优化。 * </p> * * @author LXD * @version 1.0.1 */ public final class UtilEmpty { /** * 缓存字段信息,避免重复反射调用 */ private static final ClassValue<Field[]> FIELD_CACHE = new ClassValue<Field[]>() { @Override protected Field[] computeValue(Class<?> type) { List<Field> fields = new ArrayList<>(); // 获取所有声明的字段,包括私有字段 for (Field field : type.getDeclaredFields()) { // 排除静态字段和 transient 字段 if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers())) { try { field.setAccessible(true); fields.add(field); } catch (Exception ignored) { // 忽略无法设置访问权限的字段(如模块系统限制) } } } return fields.toArray(new Field[0]); } }; /** * 私有构造函数,防止实例化 */ private UtilEmpty() { throw new UnsupportedOperationException("Utility class"); } // ================================================================================= // 核心判空方法 (Overloads for Performance) // ================================================================================= /** * 检查字符串是否为空 * * @param str 字符串 * @return 如果字符串为 null 或仅包含空白字符,则返回 true */ public static boolean isNull(String str) { return isBlank(str); } /** * 检查集合是否为空 * * @param collection 集合 * @return 如果集合为 null 或不包含元素,则返回 true */ public static boolean isNull(Collection<?> collection) { return collection == null || collection.isEmpty(); } /** * 检查 Map 是否为空 * * @param map Map * @return 如果 Map 为 null 或不包含映射,则返回 true */ public static boolean isNull(Map<?, ?> map) { return map == null || map.isEmpty(); } /** * 检查对象数组是否为空 * * @param array 数组 * @return 如果数组为 null 或长度为 0,则返回 true */ public static boolean isNull(Object[] array) { return array == null || array.length == 0; } /** * 检查数值是否为 null (注意:0 不会被视为 null) * * @param number 数值 * @return 如果数值为 null,则返回 true */ public static boolean isNull(Number number) { return number == null; } /** * 检查布尔值是否为 null (注意:false 不会被视为 null) * * @param bool 布尔值 * @return 如果布尔值为 null,则返回 true */ public static boolean isNull(Boolean bool) { return bool == null; } // ================================================================================= // 通用判空方法 // ================================================================================= /** * 检查对象是否为空 * <p> * 规则:<br> * 1. null -> true <br> * 2. CharSequence -> 仅包含空白字符时为 true<br> * 3. Collection/Map -> isEmpty() 为 true<br> * 4. Array -> length == 0 为 true<br> * 5. Optional -> !isPresent() 为 true<br> * 6. Iterator/Iterable -> !hasNext() 为 true<br> * 7. 其他对象 (POJO) -> 递归检查所有字段,若所有字段均为空则返回 true<br> * 注意:java.* 和 javax.* 开头的类被视为值对象,只要不为 null 即视为不为空<br> * </p> * * @param object 要检查的对象 * @return 如果对象符合上述空值规则,则返回 true */ public static boolean isNull(Object object) { if (object == null) { return true; } // 优先检查最常见的类型 if (object instanceof String) { return isBlank((String) object); } if (object instanceof Collection) { return ((Collection<?>) object).isEmpty(); } if (object instanceof Map) { return ((Map<?, ?>) object).isEmpty(); } if (object instanceof Object[]) { return ((Object[]) object).length == 0; } // 处理其他特定类型 if (object instanceof CharSequence) { return isBlank((CharSequence) object); } // 原始类型数组处理 (int[], byte[] 等) Class<?> clazz = object.getClass(); if (clazz.isArray()) { return Array.getLength(object) == 0; } if (object instanceof Optional) { return !((Optional<?>) object).isPresent(); } if (object instanceof Iterable) { return !((Iterable<?>) object).iterator().hasNext(); } if (object instanceof Iterator) { return !((Iterator<?>) object).hasNext(); } // 基本类型包装类、Number、Boolean、Date 等通常被视为值对象,不应被递归检查 // 为了安全和性能,跳过 JDK 内部类的反射检查 String className = clazz.getName(); if (className.startsWith("java.") || className.startsWith("javax.")) { return false; } // POJO 反射检查 (作为最后手段) return isPojoEmpty(object, clazz); } // ================================================================================= // 扩展辅助方法 // ================================================================================= /** * 检查对象是否不为空 * * @param object 对象 * @return 如果对象不为空,则返回 true */ public static boolean isNotNull(Object object) { return !isNull(object); } /** * 检查数值是否为 null 或 0 * <p> * 适用于需要将 0 视为"空"的特定业务场景 * </p> * * @param number 数值 * @return 如果数值为 null 或 0,则返回 true */ public static boolean isNullOrZero(Number number) { if (number == null) { return true; } if (number instanceof BigDecimal) { return BigDecimal.ZERO.compareTo((BigDecimal) number) == 0; } if (number instanceof BigInteger) { return BigInteger.ZERO.compareTo((BigInteger) number) == 0; } if (number instanceof Double || number instanceof Float) { return number.doubleValue() == 0.0; } return number.longValue() == 0L; } // ================================================================================= // 私有实现细节 // ================================================================================= /** * 检查 POJO 对象是否所有字段都为空 * * @param object 对象实例 * @param clazz 对象类 * @return 如果所有字段都为空,则返回 true */ private static boolean isPojoEmpty(Object object, Class<?> clazz) { Field[] fields = FIELD_CACHE.get(clazz); if (fields.length == 0) { // 如果对象没有字段(且不是上述已知集合类型),则视为不为空(即它本身就是一个非空对象实例) return false; } for (Field field : fields) { try { Object value = field.get(object); // 只要有一个字段不为空,整个对象就不为空 if (!isNull(value)) { return false; } } catch (IllegalAccessException e) { // 理论上不会发生,因为在 cache 中已经 setAccessible(true) // 如果发生,为了安全起见,认为该字段不为空(保守策略)或忽略该字段 // 这里选择忽略该字段继续检查其他字段 } } // 所有字段都为空 return true; } /** * 检查 CharSequence 是否为空或空白 */ private static boolean isBlank(CharSequence cs) { int length; if (cs == null || (length = cs.length()) == 0) { return true; } for (int i = 0; i < length; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 22:27:47

WindowResizer:Windows窗口尺寸控制的终极解决方案

WindowResizer&#xff1a;Windows窗口尺寸控制的终极解决方案 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为无法调节某些应用程序窗口大小而烦恼吗&#xff1f;WindowRes…

作者头像 李华
网站建设 2026/9/2 1:40:50

50、Linux系统问题排查与性能监控指南

Linux系统问题排查与性能监控指南 1. Linux系统常见问题及解决办法 1.1 串口配置问题 在Linux系统中,串口配置不当是常见问题。调制解调器设备被系统识别为串口设备,但很多调制解调器与连接到计算机主板的串口使用相同的IRQ和I/O地址设置,从而导致参数冲突。此外,一些串…

作者头像 李华
网站建设 2026/9/2 9:38:48

Windows系统文件Search.ProtocolHandler.MAPI2.dll丢失 下载修复

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/9/2 20:39:51

星火研创队

序号日期工作内容完成情况工作饱和度12025.12.8聚焦互动行为信息管理模块&#xff0c;完成后台对用户评论、点赞数据的查看页面搭建&#xff0c;能在后台列表展示基础数据&#xff0c;调整了页面字段显示样式。较好522025.12.9完善互动行为管理操作功能&#xff0c;实现后台对违…

作者头像 李华
网站建设 2026/9/2 14:22:02

如何高效配置MPLS?企业网络优化的痛点

有时候&#xff0c;你可能觉得自己的公司网络就像是一条繁忙的高速公路&#xff0c;在高峰期总是堵得水泄不通。这时候&#xff0c;MPLS(多协议标签交换)就成了解决拥堵的一剂良药。但问题是&#xff0c;如何才能让它发挥最大效用呢?很多企业在初次接触MPLS时&#xff0c;往往…

作者头像 李华
网站建设 2026/9/2 8:21:04

技术并购视角:AIGC领域的 Web 生态整合与资源重组

一、AIGC——当“内容”开始自己生长在过去的十年&#xff0c;AIGC (AI Generated Content) 从学术论文里的冷僻缩写&#xff0c;华丽转身为市场的宠儿。 如今&#xff0c;AI 不仅能写&#xff08;比如我&#x1f44b;&#xff09;&#xff0c;还能画、能唱、能推理、能陪你聊人…

作者头像 李华