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 文件)
| # |
级别 |
类型 |
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+ 推荐) |
|
| # |
级别 |
类型 |
整体 |
描述 |
| — |
✅ |
— |
— |
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
- [Blocker] RSA.java:262 —
switch 表达式改 if-else,直接影响 jre8 编译
- [Blocker] JwtUtil.java:173 —
var 改显式类型,同上
- [Blocker] JwtUtil.java:52 —
instace() → instance(),API 拼写错误
- [Blocker] RequestHeader.java:121 —
geRespTime() → getRespTime()
- [Blocker] FileUtil.java:295 & ImgUtil.java:266 —
connectBytes() 数组拷贝 Bug 修正
- [Major] ObjUtil.java:393 —
System.out.println → 日志框架
- [Major] util 包整体 — 补齐 @param/@return/@throws Javadoc(优先工具类:StrUtil, FileUtil, JsonUtil)
- [Major] DateTimeUtil.java — 30+ 方法补齐 @return/@param 描述
- [Major] FileUtil.java — 统一日志框架 + 清理异常包装
- [Major] MoneyUtil.java |
toFen() 返回值类型修正 + 补齐 Javadoc
报告生成时间: 2026-05-15
审计工具: Code Reviewer Expert (SonarLint / Checkstyle 标准)