Files
Java_ConstractUtil/readme.md
T
2026-05-17 09:32:34 +08:00

150 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 我的公众号
![](.readme/B5F8E89A-CE33-4a78-A461-E9014B10A3D9.png)
# Java_ConstractUtil
通用的Java同类型对象对比工具类,用于比较两个同类型对象的属性差异,并返回变化的部分。
---
## 快速开始
### Maven依赖
```xml
<dependency>
<groupId>Java_ConstractUtil</groupId>
<artifactId>Java_ConstractUtil</artifactId>
<version>1.0.0</version>
</dependency>
```
### 基本使用
```java
// 比较两个同类型对象
SimpleObj origin = new SimpleObj();
origin.setX(1);
origin.setY("hello");
SimpleObj target = new SimpleObj();
target.setX(2);
target.setY("hello");
ContrastObject<SimpleObj> result = ContrastUtil.contrast(origin, target);
if (result != null) {
// result.getOriginChange() -> 原始对象中发生变化的属性 (x=1)
// result.getTargetChange() -> 修改后对象中发生变化的属性 (x=2)
System.out.println(result.getOriginChange().getX()); // 1
System.out.println(result.getTargetChange().getX()); // 2
}
```
---
## 工具说明
### ContrastUtil(通用对比工具)
`ContrastUtil` 是默认的对象对比实现类,提供静态方法 `contrast(T origin, T target)` 进行对象对比。
**处理规则:**
1. **基本类型和包装类型**:直接使用 `equals` 进行比较(如 `int``String``Date` 等)
2. **Collection类型**:比较两个集合的差异,返回差集。仅处理一层,泛型内的元素直接调用 `equals` 比较
3. **Map类型**:比较两个Map的差异,包括相同key的value比较和不同key的差异
4. **自定义类型**:调用 `equals` 方法进行比较,**要求重写 `equals``hashCode` 方法**,否则会比较对象地址
5. **类型一致性**:比较的两个对象类型必须一致,否则抛出 `TypeMisMatchException`
6. **空值处理**:入参可以为 `null`,两者都为 `null` 返回 `null`,其中一个为 `null` 则返回非空一方的结果
7. **Getter/Setter检查**:自定义类型必须有完整的 `get`/`set` 方法,否则抛出 `NoGetMethodException` / `NoSetMethodException`
8. **抽象类和接口**:不支持抽象类和接口的实例对比,会直接返回 `null`
**返回值说明:**
`ContrastObject<T>` 包含四个字段:
- `origin`:原始对象(完整)
- `target`:修改后的对象(完整)
- `originChange`:原始对象中**发生变化**的属性(新实例,仅包含变化的字段)
- `targetChange`:修改后对象中**发生变化**的属性(新实例,仅包含变化的字段)
无变化时返回 `null`
---
### AbstractContrastUtil(抽象基类)
`AbstractContrastUtil<T>` 提供最大的自定义性,使用者可以通过继承并实现抽象方法来定制各种类型的对比逻辑。
**需要实现的抽象方法:**
| 方法 | 说明 |
|------|------|
| `originContract()` | 基本类型和包装类型的对比逻辑 |
| `selfContract()` | 自定义类型的对比逻辑 |
| `mapContract()` | Map类型的对比逻辑 |
| `collectionContract()` | Collection类型的对比逻辑 |
| `specialContract()` | 特殊类型的自定义处理逻辑 |
| `isSpecialType()` | 判断是否为特殊类型(优先于Collection/Map判断) |
| `nullProcessor()` | 入参为null的处理逻辑 |
| `originProcessor()` | 基本类型入参的处理逻辑 |
| `setContrastObject()` | 组装返回结果对象 |
**使用示例:** 参考 [ContrastUtilExample.java](src/main/java/ContrastUtilExample.java)
---
## 项目结构
```
src/main/java/
├── ContrastUtil.java # 默认对比工具实现
├── AbstractContrastUtil.java # 抽象对比基类
├── ContrastUtilExample.java # 抽象基类使用示例
├── bean/
│ └── ContrastObject.java # 对比结果包装类
├── constant/
│ └── Constant.java # 常量定义
├── exception/
│ ├── NoGetMethodException.java # 缺少getter方法异常
│ ├── NoSetMethodException.java # 缺少setter方法异常
│ └── TypeMisMatchException.java # 类型不匹配异常
├── handler/
│ ├── CollectionHandler.java # Collection类型处理器
│ ├── MapHandler.java # Map类型处理器
│ ├── OriginHandler.java # 基本类型处理器
│ └── SelfHandler.java # 自定义类型处理器
└── util/
├── CheckUtil.java # 类型检查工具
├── ClassUtil.java # 类反射工具
├── CollectionUtil.java # 集合差异计算工具
├── MapUtil.java # Map工具
└── SetUtil.java # Set工具
```
---
## 依赖
| 依赖 | 版本 | 用途 |
|------|------|------|
| commons-lang3 | 3.9 | 通用工具 |
| commons-collections4 | 4.4 | 集合工具 |
| guava | 28.2-jre | Google工具库 |
| reflectasm | 1.11.0 | 高性能反射 |
---
## 注意事项
1. Collection和Map仅处理一层,嵌套的泛型类型直接调用 `equals` 比较,可能导致结果不准确。如需深度对比,请使用 `AbstractContrastUtil` 自定义处理逻辑
2. 自定义类型**必须重写 `equals``hashCode` 方法**,否则会比较对象地址而非值
3. 当前使用 reflectASM 进行反射调用,性能优于标准反射,但仍有优化空间
4. 暂不支持 `is` 前缀的 boolean getter 方法(如 `isActive()`),后续版本会支持
---
## 更新日志
- **2020/4/30**:创建项目,完成初始实现和单元测试
- **2020/5/9**:添加测试方法,修复反射处理null的空指针问题,创建抽象类和继承使用示例
- **2026/5/17**:修复多个bugMapHandler参数错误、OriginHandler空值比较逻辑、ContrastObject NPE风险等),优化代码实现,补全注释和文档