17 KiB
17 KiB
代码审查报告
文件: data\demo-pmd\src\com\demo\design\extra\GodClassDemo.java
语言: java
耗时: 197.9s
分析工具: pmd
总计: 84 | 错误: 3 | 警告: 78 | 建议: 3
静态分析 · 79 个问题
- 🔴
pmd:AvoidReassigningParametersL57 L57: 避免对参数 'x' 重新赋值 建议: 在方法内使用局部变量保存 x 的初始值,并对局部变量进行递减操作,保持参数不变。 - 🔴
pmd:AvoidReassigningParametersL78 L78: 避免对参数 'x' 重新赋值 建议: 在方法内使用局部变量保存 x 的初始值,并对局部变量进行递减操作,保持参数不变。 - 🔴
pmd:SystemPrintlnL181 L181: 使用了 System.out/err 输出 建议: 使用日志框架(如 java.util.logging、SLF4J、Log4j2)记录信息,便于日志管理与级别控制。 - 🟡
pmd:AtLeastOneConstructorL9 L9: 每个类应至少声明一个构造函数 建议: 为类添加构造函数;若无需初始化逻辑,可声明一个空的包可见构造函数。 - 🟡
pmd:DataClassL9 L9: 类 'ExternalData' 被怀疑是数据类(WOC=0.000%, NOPA=10, NOAM=0, WMC=0) 建议: 将公共字段改为私有,并添加构造器与行为方法;或使用 Java record 作为不可变数据传输对象(Java 14+)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'a' 应降低可见性 建议: 将字段 a 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'b' 应降低可见性 建议: 将字段 b 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'c' 应降低可见性 建议: 将字段 c 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'd' 应降低可见性 建议: 将字段 d 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'e' 应降低可见性 建议: 将字段 e 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'f' 应降低可见性 建议: 将字段 f 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'g' 应降低可见性 建议: 将字段 g 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'h' 应降低可见性 建议: 将字段 h 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'i' 应降低可见性 建议: 将字段 i 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:PublicMemberInNonPublicTypeL10 L10: 非公共类型 'ExternalData' 中的公共成员 'j' 应降低可见性 建议: 将字段 j 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。 - 🟡
pmd:AtLeastOneConstructorL14 L14: 每个类应至少声明一个构造函数 建议: 为 GodClassDemo 添加构造函数;若该类仅作为工具类,建议将构造函数设为 private 禁止实例化。 - 🟡
pmd:GodClassL14 L14: 疑似上帝类(WMC=89, ATFD=105, TCC=0.000%) 建议: 按单一职责将 GodClassDemo 拆分为多个类,将规则方法分组到不同类,并提升方法内聚性、降低对外部数据类的直接访问。 - 🟡
pmd:MethodArgumentCouldBeFinalL16 L16: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL16 L16: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL18 L18: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL19 L19: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:MethodArgumentCouldBeFinalL22 L22: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL22 L22: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL24 L24: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL25 L25: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:MethodArgumentCouldBeFinalL28 L28: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL28 L28: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL34 L34: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL34 L34: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL46 L46: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL46 L46: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL52 L52: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:AvoidLiteralsInIfConditionL56 L56: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 x > THRESHOLD_10。 - 🟡
pmd:MethodArgumentCouldBeFinalL61 L61: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL61 L61: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL69 L69: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL82 L82: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL82 L82: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL84 L84: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL84 L84: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:AvoidLiteralsInIfConditionL85 L85: 避免在 if 语句中使用字面量(如 3) 建议: 定义常量并替换:private static final int THRESHOLD_3 = 3; 条件改为 x > THRESHOLD_3。 - 🟡
pmd:MethodArgumentCouldBeFinalL88 L88: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL88 L88: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL97 L97: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL97 L97: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL99 L99: 避免在 if 语句中使用字面量(如 5) 建议: 定义常量并替换:private static final int THRESHOLD_5 = 5; 条件改为 x > THRESHOLD_5。 - 🟡
pmd:AvoidLiteralsInIfConditionL100 L100: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 x > THRESHOLD_10。 - 🟡
pmd:MethodArgumentCouldBeFinalL103 L103: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL103 L103: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:TooFewBranchesForSwitchL106 L106: 分支少于三个的 switch 效率较低,建议改用 if 语句 建议: 将 switch (i % 2) 改为 if-else:if (i % 2 == 0) { r += d.a; } else { r += d.b; } - 🟡
pmd:AvoidLiteralsInIfConditionL111 L111: 避免在 if 语句中使用字面量(如 5) 建议: 定义常量并替换:private static final int THRESHOLD_5 = 5; 条件改为 x > THRESHOLD_5。 - 🟡
pmd:MethodArgumentCouldBeFinalL114 L114: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL114 L114: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL116 L116: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL117 L117: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:MethodArgumentCouldBeFinalL120 L120: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL120 L120: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL122 L122: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL123 L123: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:MethodArgumentCouldBeFinalL126 L126: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL126 L126: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL128 L128: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL129 L129: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:MethodArgumentCouldBeFinalL132 L132: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL132 L132: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL135 L135: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 i > THRESHOLD_10。 - 🟡
pmd:AvoidLiteralsInIfConditionL135 L135: 避免在 if 语句中使用字面量(如 20) 建议: 定义常量并替换:private static final int THRESHOLD_20 = 20; 条件改为 i > THRESHOLD_20。 - 🟡
pmd:MethodArgumentCouldBeFinalL140 L140: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL140 L140: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:AvoidLiteralsInIfConditionL142 L142: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。 - 🟡
pmd:AvoidLiteralsInIfConditionL142 L142: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。 - 🟡
pmd:AvoidLiteralsInIfConditionL143 L143: 避免在 if 语句中使用字面量(如 3) 建议: 定义常量并替换:private static final int THRESHOLD_3 = 3; 条件改为 x > THRESHOLD_3。 - 🟡
pmd:MethodArgumentCouldBeFinalL146 L146: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL146 L146: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL152 L152: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL152 L152: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🟡
pmd:MethodArgumentCouldBeFinalL168 L168: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 final:final ExternalData d。 - 🟡
pmd:MethodArgumentCouldBeFinalL168 L168: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 final:final int x。 - 🔵
pmd:OneDeclarationPerLineL10 L10: 每行只声明一个变量,以增强代码可读性 建议: 将同一行的多个变量声明拆分为多行,每行一个变量。
AI 审查 · 5 条建议
- 🟡 [AI] [bug]
potential-null-dereferenceL16 ExternalData 参数未做空值校验 所有 rule* 方法直接使用参数 d 的字段,未校验 d 是否为 null。当外部传入 null 时,方法会立即抛出 NullPointerException。 建议: 在每个方法入口增加防御性判断,如 if (d == null) throw new IllegalArgumentException("d must not be null");或使用 Objects.requireNonNull(d) 统一校验。 - 🟡 [AI] [bug]
unreachable-branch-in-if-else-ifL18 if-else if 条件顺序导致后续分支不可达 rule1、rule2、rule9、rule11、rule13、rule14、rule15、rule16、rule17 等方法中的 if-else if 链按从小到大判断,例如 rule1 中 if (x>0) 已覆盖所有正数,其后的 else if (x>1) 与 else if (x>2) 永远无法执行。 建议: 调整判断顺序,将范围更大的条件放在前面,或改用区间判断(如 x > 0 && x <= 1)。请根据业务语义改为正确的分段逻辑。 - 🟡 [AI] [bug]
tautological-conditionL31 条件表达式恒为真 rule3(L31)与 rule18(L149)中的 if (x > 1 || x < 20) 对任意整数 x 均成立,导致其分支总被执行,原条件失去判断意义。 建议: 检查业务意图。如果希望同时满足两个条件,应改为 if (x > 1 && x < 20);如果确实无条件执行,应移除 if 直接执行。 - 🔵 [AI] [design]
meaningless-method-namesL16 规则方法使用无意义的数字命名 rule1 到 rule20 的方法名无法描述业务行为,难以维护和理解。数字命名还暗示这些方法可能由复制粘贴生成,代码重复度高。 建议: 根据业务语义重命名方法(如 calculateDiscount、applyTax 等),并提取重复逻辑为公共方法。 - 🔵 [AI] [performance]
inefficient-nested-loopL90 rule10 存在 O(n²) 复杂度且可能产生巨大循环 rule10 使用双重 for 循环(L90-94),当 x 较大时会造成严重的性能问题;若 x 来自用户输入,可能形成拒绝服务攻击。 建议: 评估业务逻辑,避免将未受控的外部输入直接作为循环上限;考虑降低时间复杂度或增加上限校验。