Java深比较基于Object.getClass()与反射实现:通过@DiffProperty注解标记需比对字段,递归处理复合对象,用WeakHashMap防循环引用,结构化输出差异详情并特殊处理集合、数组及BigDecimal等类型。

Java 中 Object 类本身不直接参与深比较逻辑,但它提供了基础支撑:所有对象天然继承自 Object,因此能统一调用 equals()、getClass()、toString() 等方法;更重要的是,getClass() 和反射配合,是遍历字段、读取注解、判断类型、递归处理嵌套对象的前提。
用 @DiffProperty 注解标记需比对的字段
定义一个运行时保留的字段级注解,明确“哪些字段要参与比较”以及“如何展示差异”:
-
@Target(ElementType.FIELD)表示只能标注在属性上 -
@Retention(RetentionPolicy.RUNTIME)确保运行时可通过反射获取 - 支持
name()自定义显示名(如把userCode显示为“用户编码”) - 不加该注解的字段默认跳过,避免无意义比对
基于 Object.getClass() 获取真实类型并安全反射
两个对象可能类型相同,但运行时实例可能是子类或代理类。必须用 obj.getClass() 而非 obj.getClass().getSuperclass() 或硬编码类名:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 调用
Class.getDeclaredFields()获取本类所有字段(含 private) - 对每个字段检查是否带有
@DiffProperty,跳过未标注字段 - 用
field.setAccessible(true)访问私有字段值,再通过field.get(obj)读取 - 若字段值为
null,直接记录为null;若为基本类型包装类或字符串,直接用equals()比较
对非基本类型字段递归调用深比较逻辑
当字段类型不是 String、Number、Boolean、Enum、Date 等可直比类型时,视为复合对象,需递归处理:
立即学习“Java免费学习笔记(深入)”;
- 先确认两个值都不为
null,且属于同一具体类(用getClass()判断) - 若类型实现了自定义
equals(),可尝试调用——但为保证一致性,建议统一走反射路径 - 对
List、Map等集合,需逐项比对(例如按索引比List,按 key 比Map),并支持嵌套深度限制防止栈溢出 - 用
WeakHashMap<object boolean></object>缓存已比对过的对象对,防止循环引用导致无限递归
结果封装与空值/类型差异处理
对比结果不应只返回 boolean,而应结构化输出差异细节,方便日志、审计或前端展示:
- 每个差异项包含:字段名(或
@DiffProperty.name())、A 值、B 值、是否为null、类型是否一致 -
BigDecimal、Timestamp等特殊类型需单独处理(如compareTo()或毫秒值比对) - 对
Arrays,不能直接用equals()(它比较引用),要用Arrays.deepEquals() - 缓存已解析的类字段信息(如
ConcurrentHashMap<class>, List<field>></field></class>),避免重复反射开销

















