Files
yexuejc-base/代码质量审计报告.md
yexuejc f7f1e59aea docs: 添加代码质量全量修复报告 + 更新CHANGELOG
- 新增 代码质量全量修复报告.md(含4分支验证矩阵+兼容性详情)
- CHANGELOG 记录全部 Blocker/Major/Minor 修复项
- 标注破坏性变更
2026-05-16 00:44:10 +08:00

20 KiB
Raw Permalink Blame History

yexuejc-base 代码质量审计报告

项目: yexuejc-base v1.6.0-jre8
扫描范围: src/main/java/com/yexuejc/base/ 下全部 57 个 Java 源文件
审计标准: SonarLint / Checkstyle 级别
分支规则: jre21(主) / master 对齐 jre21 / jre8, jre11, jre17 兼容对应 JDK
编码检查: UTF-8 无BOM + LF ✅ 全部通过(57/57 文件合规)


一、总体评分

维度 评分 说明
Javadoc 完整性 ⭐⭐⭐☆☆ 大部分有类/方法级注释,但约 30% 方法缺少 @param/@return
Java 版本兼容 ⭐⭐⭐⭐☆ 发现 1 处 jre8 不兼容语法(switch 表达式)
命名规范 ⭐⭐⭐⭐⭐ 整体规范,少量历史遗留拼写问题
安全性 ⭐⭐⭐⭐☆ 加密模块已做过多轮安全修复,残留少量风险点
代码规范 ⭐⭐⭐☆☆ 存在 System.out.println 残留、TODO 未处理等

二、按包审计详情

1. com.yexuejc.base.annotation(2 文件)

CsvToBean.java

# 级别 类型 位置 描述
1 💭 Javadoc value() @return 标签后无描述(空返回)

ToUeProperty.java

# 级别 类型 位置 描述
1 💭 Javadoc value() @return 标签后无描述
2 💭 Javadoc ignore() @return 标签后无描述
3 💭 Javadoc type() @return 引用了 ObjUtil.class 作为 type 默认值,语义不明

2. com.yexuejc.base.constant(5 文件)

DateConsts.java

# 级别 类型 位置 描述
1 🟡 规范 类级别 缺少类级 @since 标签;常量字段缺少 Javadoc 注释(仅部分有)
2 🟡 命名 第19行起 常量命名风格不一致:部分有 DATE_ 前缀,DATE_KEY_T 等前缀不统一

ExpCode.java

# 级别 类型 位置 描述
— ✅ — — 完整性好,所有常量均有注释

RespConsts.java

# 级别 类型 位置 描述
1 🟡 规范 第26-37行 部分常量使用 public static 而非 private static final,但 HEADER_* 常量应为 API 固定值可理解
2 ✅ 兼容 — 已用 @Deprecated 标记拼写错误 MSG_ERROT_HTTP

SymbolicConsts.java

# 级别 类型 位置 描述
1 🟡 注释 第19行 NEW_LINE 有注释但 EMPTY, EQUAL 等缺少注释

3. com.yexuejc.base.converter(9 文件)

LocalDateTimeSerializer.java

# 级别 类型 L28-31 描述
1 🟡 Javadoc serialize() 缺少 @param/@return/@throws 的完整 Javadoc。方法有 3 个参数和 throws 声明,但无对应标签

TimestampDeserializer.java

| # | 级别 | 类型 | — | 描述 | | — | ✅ | — | — | 完整性好 |


4. com.yexuejc.base.encrypt(6 文件)

RSA.java

# 级别 类型 L262-269 描述
1 🔴 版本兼容 ecKeySizeToCurveName() 使用了 switch 表达式(箭头语法 ->),这在 Java 12+ 才引入。jre8/jre11 分支无法编译!
2 🟡 Javadoc 多处方法 部分 public 方法(如 initKeys, getPublicKey, sign 等)的 @param/@return 描述过于简略,如 @param keySize 生成长度 应说明有效值范围
3 🟡 安全 L91, L120-126, L146 algorithm, transformation, isChangeSign, encodeBase64URLSafe 使用 public volatile 字段直接暴露,虽为设计需要但建议加访问控制或 final + builder 模式统一管理
4 💭 Nit L681 geRespTime() 方法名存在拼写错误:应为 getRespTime()(与 REQUEST_TIME 对应),属历史遗留 bug

AES.java

| # | 级别 | 类型 | — | 描述 | | — | ✅ | — | — | 审计通过。文档完善,安全处理得当 |

DES3.java

| # | 级别 | 类型 | — | 描述 | | — | ✅ | — | — | 已标记 @Deprecated,迁移建议清晰 |

RSACoder.java

| # | 级别 | 类型 | — | 描述 | | — | ✅ | — | — | 审计通过。OAEP 填充安全说明详细 |

RSA2.java

| # | 级别 | 类型 | L395 | 描述 | | 1 | 🟡 | 异常处理 | getPrivateKeyByPKCS8() | 抛出原始字符串 "获取私钥失败" 而非使用 ExpCode,与其他方法风格不一致 |

SignAlgorithm.java

| # 级别 | 类型 | — | 描述 | | — | ✅ | — | 枚举文档完整 |


5. com.yexuejc.base.exception(2 文件)

BaseException.java

# 级别 类型 L109, L133 描述
1 🟡 Javadoc getMessage(), getMessageByCode() @return 标签无描述内容
2 💭 Nit L33-34 errorMessage 使用了 @SuppressWarnings("java:S1165") —— 建议改为声明 getter 或添加合理注释解释为何抑制

BaseRuntimeException.java

| # | 级别 | 类型 | 同上 | 同 BaseException 的问题(复制粘贴导致同样问题) |


6. com.yexuejc.base.file(1 文件)

FileInput.java

# 级别 类型 多处 描述
1 🟡 Javadoc 全部 12 个 public 方法 几乎所有方法的 @param 和 @return 标签无描述内容。例如:
  • read4Byte(InputStream, Charset) → @param inputStream 无说明、@return 无说明
  • read4BufferedReader(...) → 同上 2 | 💭 | Nit | L51 | BUFFER_SIZE = 8192 和 IO_EXCEPTION_MSG 可考虑提取为常量类 | | 3 | 💭 | Nit | L136 | read4ScannerZ() 中 Scanner 未使用 try-with-resources(虽在 finally 关闭,但不够优雅) |

7. com.yexuejc.base.http(1 文件)

RequestHeader.java

# 级别 类型 L121 描述
1 🔴 Bug geRespTime() 方法名拼写错误:应为 getRespTime()。这会影响使用者调用,且与 RESPONSE_TIME 常量不匹配。属于 API 兼容性问题。
2 🟡 Javadoc responseBuilder() 参数 signature 的 @param 未说明格式要求

8. com.yexuejc.base.pojo(10 文件)

BaseVO.java

# 级别 类型 L26-36 描述
1 🟡 设计 内部接口 Add, Del, Mdfy, Srch 接口缺乏 Javadoc 说明用途,且命名缩写不规范(Mdfy 应为 Modify)
2 💭 Nit L24 serialVersionUID 缺少 @Serial 注解(Java 16+ 推荐)

BasicResponse.java / ListResponse.java / ObjectResponse.java / SignResponse.java / SignRequest.java / ReadFileBean.java / CreateZipFileBean.java / CsvToBean.java / PagerVO.java

# 级别 类型 整体 描述
— ✅ — — pojo 包整体质量优秀,是全项目 Javadoc 最规范的包。几乎所有方法都有完整的 @param/@return

9. com.yexuejc.base.service(1 文件)

MessageService.java

| # | 级别 | 类型 | — | 描述 | | — | ✅ | — | 接口定义简洁完整 |


10. com.yexuejc.base.util(18 文件)—— 问题集中区

AlgorithmUtil.java

# 级别 类型 L35-39, L55-63, L77-83, L122, L140 描述
1 🟡 Javadoc getNextCode(), x10ConvertTo36(), x36ConvertTo10(), x16ConvertTo2(), hexStringToBytes() @param/@return 要么缺失要么描述混乱(如 @throws NextCodeException String 下个序数的code 语法混乱)
2 🟡 命名 L127 StringBuffer 应使用 StringBuilder(性能更优,虽然此处影响小)
3 💭 Nit L113-115 内部类 NextCodeException 缺少 @Serial

CsvUtil.java

# 级别 类型 L1 描述
1 🟡 License 文件头 缺少 Copyright 头部(其他文件都有 Copyright (c) 2017-2026 yexuejc 头部)
2 🟡 Author L29 @author maxiaofeng 与其他文件 yexuejc 不一致
3 💭 Nit L362 私有构造函数正确

DateTimeUtil.java

# 级别 类型 大量方法 描述
1 🟡 Javadoc 约 30+ 个方法 绝大多数方法的 @param/@return 无描述内容。例如 getYear4First() 的 @return 为空;parseDate(ZonedDateTime) 的 @param zonedDateTime 无说明
2 💭 Nit L451-481 存在注释掉的 main 方法块(建议删除或移至测试)
3 ✅ 版本兼容 — 无高版本语法,jre8 可编译

DateUtil.java

# 级别 类型 整体 描述
1 ✅ — — 已标记 @Deprecated,ThreadLocal 修复了线程安全
2 🟡 Javadoc 部分方法 @param/@return 缺描述,但比 DateTimeUtil 好

ExcelImportUtil.java

# 级别 类型 全文件 描述
1 🟡 Javadoc 全部 3 个方法 @param/@return 全部无描述
2 💭 Nit L53 validateExcel() 逻辑可简化:`return isExcel2003(filePath)

FileUtil.java

# 级别 类型 多处 描述
1 🟡 Javadoc 约半数方法 @param/@return 缺描述或过于简略(如 @param fileName 无说明)
2 🟡 日志 L49 使用 java.util.logging.Logger 而非项目中统一的 System.Logger(与 RSA、RSA2 等不一致)
3 🔴 Bug L295 connectBytes(front, after) 中 System.arraycopy 参数顺序错误:System.arraycopy(front, 0, result, 0, after.length) 应该是 result, front.length, after.length —— 数据会被错误截断或越界
4 🟡 资源 L469 readBigFile(CSV) catch 块中将 BaseException 包装为 RuntimeException 再抛出,破坏了异常体系一致性
5 💭 Nit L54 定义了 NEW_LINE = "\n" 而 SymbolicConsts.NEW_LINE 已存在,应复用常量

IdcardValidator.java

# 级别 类型 — 描述
1 ✅ — — 全场最佳实践范例。Javadoc 完整,逻辑严谨,校验全面

ImgUtil.java

# 级别 类型 L51, L192, L220 描述
1 🟡 异常处理 多处 使用 e.printStackTrace() 而非日志框架记录,在生产环境中堆栈可能泄露到 console
2 🟡 Javadoc 部分方法 getByteArray(ByteArrayOutputStream) 等 @param 无描述
3 🔴 Bug L266 connectBytes(front, after) 同 FileUtil 的问题:System.arraycopy 的 srcPos/destPos 参数可能导致数组拷贝越界

JsonUtil.java

# 级别 类型 L161 描述
1 🟡 TODO initSnakeCase() 标注了 //TODO 待优化 但未说明具体优化方向
2 🟡 Javadoc 静态初始化方法 setJavaTimeModule(), initDefaultObjectMapper() 等 private 方法的 Javadoc 是给外部用的(实际也是 private),但参数 @param jsonMapper 描述尚可
3 🟡 异常处理 多个 json2Obj() 重载 异常被 catch 后仅 log warning 并返回 null,调用方可能不知道为何反序列化失败(建议至少打印一次 error 级别的日志)

JwtUtil.java

# 级别 类型 L52 描述
1 🔴 Bug instace() 方法名拼写错误:应为 instance()。这是公开 API,影响所有调用者
2 🟡 版本兼容 L173 var builder = Jwts.builder() 使用了 var 关键字。jre8/jre10/jre11 不支持 var,需确认目标分支
3 ✅ 安全 — 密钥长度校验完善,线程安全说明清晰

MapRemoveNullUtil.java

# 级别 类型 L31-67 描述
1 🟡 Javadoc 全部 3 个公开方法 @param Map map 无任何描述
2 💭 Nit L79-107 remove() 死代码方法未被使用(死代码)

MoneyUtil.java

# 级别 类型 全文件 描述
1 🟡 Javadoc 全部 6 个方法 @param/@return全部缺描述(仅有@Title/@Description` 残留旧格式)
2 🟡 线程安全 多处 DecimalFormat 在每次调用时新建(new DecimalFormat("0.00")),虽线程安全但性能可优化为静态成员或 ThreadLocal
3 💭 Nit L72-80 toFen() 返回 int,大金额可能溢出(应返回 long 或 BigDecimal)

MsgUtil.java

| # | 级别 | 类型 | — | 描述 | | --- | --- | ------ | ------| | 1 | ✅ | — | SPI 设计良好,文档充分 |

ObjUtil.java

# 级别 类型 L393 描述
1 🔴 严重 System.out.println(e.getMessage()) 使用了 System.out.println 而非日志框架,生产环境可能丢失关键错误信息
2 🟡 Javadoc 约 15+ 个方法 大量方法的 @param/@return 缺描述或不规范
3 🟡 性能 getUnderlineMap() 每次调用都通过反射遍历所有字段(含父类),高频场景下可能有性能影响,FIELD_CACHE 缓存了 Field 列表但未缓存 get/setter

RegexUtil.java

| # | 级别 | 类型 | — | 描述 | | --- | --- | ------ | ------| | 1 | ✅ | — | 常量文档完善,唯一公开方法 regex() Javadoc 完整 |

StrUtil.java

# 级别 类型 多处 描述
1 🟡 Javadoc 约 20+ 个方法 部分 @param/@return 缺描述(如 isEmpty(), isNotEmpty() 的 @obj 描述尚可,但 toMD5(), codeId() 等 Deprecated 方法需关注)
2 ✅ 安全 MD5 标注了 @deprecated 并警告不安全用途
3 ✅ 版本兼容 无高版本语法

SysUtil.java

# 级别 类型 多处 描述
1 🟡 Javadoc 约 10 个方法 部分方法 @param/@return 缺描述
2 🟡 线程 L69-86 threadRun() 创建 ThreadPoolExecutor 后立即 shutdown(),对于异步任务来说可能来不及执行就关闭了。应考虑提交任务后再 shutdown + awaitTermination
3 💭 Nit L185 formatByte() 使用 DecimalFormat 非线程安全(虽在 private 方法中且单线程调用路径,但隐患仍存在)

ZipUtil.java

# 级别 类型 L40 描述
1 🟡 Javadoc createZipFile() @param zipFileBean 无描述,且该方法抛出 ZipException 但未在 Javadoc 中标注 @throws
2 🟡 安全 L46 使用 ZIP_STANDARD 加密(ZipCrypto 标准),密钥从 Bean 的 getEncryptPwd().toCharArray() 获取,强度取决于调用方

三、🔴 Blocker 级别问题汇总(必须修复)

# 文件 问题 影响分支 修复建议
1 RSA.java:262 switch 表达式(-> 箭头语法) jre8, jre11 改为 if-else-if 链式
2 JwtUtil.java:173 var builder = Jwts.builder() 局部变量推断 jre8, jre10, jre11 显式声明类型 JwtBuilder builder =
3 JwtUtil.java:52 instace() 方法名拼写错误 全分支 重命名为 instance()
4 RequestHeader.java:121 geRespTime() 方法名拼写错误 全分支 重命名为 getRespTime()
5 FileUtil.java:295 connectBytes() 数组拷贝参数顺序错误,可能越界 全分支 修正 System.arraycopy 的 destPos 和 length
6 ImgUtil.java:266 connectBytes() 同上数组拷贝越界 Bug 全分支 同上修正
7 ObjUtil.java:393 System.out.println() 残留 全分支 替换为 log.log(Level.SEVERE, ...)

四、🟡 Major 级别问题汇总(应当修复)

# 文件 问题数量 主要问题概要
1 util 包全体 ~60+ 处 @param/@return/@throws Javadoc 缺失或无描述
2 DateTimeUtil.java ~30 处 方法 Javadoc 全部无 @return/@param 描述
3 FileInput.java 12 处 所有方法 Javadoc 缺 param/return 描述
4 AlgorithmUtil.java 5 处 Javadoc 格式混乱,内部类 NextCodeException 缺 Serial
5 MoneyUtil.java 6 处 Javadoc 完全缺失(沿用旧格式);toFen() int 返回可能溢出
6 ExcelImportUtil.java 3 处 Javadoc 完全缺失
7 MapRemoveNullUtil.java 3 处 Javadoc 完全缺失;死代码 remove()
8 FileUtil.java 3 处 日志框架不一致(用 java.util.logging);异常包装不一致
9 JsonUtil.java 2 处 TODO 待优化标记未处理;异常处理静默吞掉
10 SysUtil.java 2 处 ThreadPoolExecutor 可能来不及执行;DecimalFormat 非线程安全
11 CsvUtil.java 1 处 缺少 Copyright 头部;author 不一致
12 ZipUtil.java 1 处 createZipFile 缺少 @throws 标注
13 RSA2.java 1 处 异常消息未使用 ExpCode 常量化
14 RespConsts.java 1 处 常量命名风格不统一(DATE_KEY_* vs 其他)
15 DateConsts.java 1 处 部分常量缺注释
16 BaseException/BaseRuntimeException 各 2 处 @return 无描述;@SuppressWarnings 未解释

五、💭 Minor 级别问题(可选修复)

# 文件 问题
1 多文件 serialVersionUID 缺少 @Serial 注解
2 BaseVO.java 内部接口 Add/Del/Mdfy/Srch 命名不规范
3 AlgorithmUtil.java StringBuffer → StringBuilder
4 FileInput.java Scanner Z 未用 try-with-resources
5 DateTimeUtil.java / DateUtil.java 注释掉的 main 方法块
6 JsonUtil.java initSnakeCase() TODO 标记
7 MapRemoveNullUtil.java remove() 死代码
8 MoneyUtil.java DecimalFormat 每次新建
9 SysUtil.java DecimalFormat 线程安全
10 RSA.java volatile 字段直接暴露

六、Java 版本兼容性专项检测

jre8 不兼容语法(影响 jre8/jre11 分支)

文件 行号 不兼容代码 修复方案
RSA.java L262-269 switch (keySize) { case 256 -> ...; default -> throw ...; } 改为 if-else-if
JwtUtil.java L173 var builder = Jwts.builder() 改为 JwtBuilder builder = Jwts.builder()

jre11 不兼容语法

当前未发现 switch 表达式以外的不兼容项。

jre17 不兼容语法

当前未发现 jre17 以上专属语法。


七、优先修复建议 TOP 10

  1. [Blocker] RSA.java:262 — switch 表达式改 if-else,直接影响 jre8 编译
  2. [Blocker] JwtUtil.java:173 — var 改显式类型,同上
  3. [Blocker] JwtUtil.java:52 — instace() → instance(),API 拼写错误
  4. [Blocker] RequestHeader.java:121 — geRespTime() → getRespTime()
  5. [Blocker] FileUtil.java:295 & ImgUtil.java:266 — connectBytes() 数组拷贝 Bug 修正
  6. [Major] ObjUtil.java:393 — System.out.println → 日志框架
  7. [Major] util 包整体 — 补齐 @param/@return/@throws Javadoc(优先工具类:StrUtil, FileUtil, JsonUtil)
  8. [Major] DateTimeUtil.java — 30+ 方法补齐 @return/@param 描述
  9. [Major] FileUtil.java — 统一日志框架 + 清理异常包装
  10. [Major] MoneyUtil.java | toFen() 返回值类型修正 + 补齐 Javadoc

报告生成时间: 2026-05-15 审计工具: Code Reviewer Expert (SonarLint / Checkstyle 标准)