Files
2026Technology-Competition/data/demo-pmd/reports/GodClassDemo-review.md
T

17 KiB
Raw Blame History

代码审查报告

文件: data\demo-pmd\src\com\demo\design\extra\GodClassDemo.java 语言: java 耗时: 197.9s 分析工具: pmd


总计: 84 | 错误: 3 | 警告: 78 | 建议: 3

静态分析 · 79 个问题

  • 🔴 pmd:AvoidReassigningParameters L57 L57: 避免对参数 'x' 重新赋值 建议: 在方法内使用局部变量保存 x 的初始值,并对局部变量进行递减操作,保持参数不变。
  • 🔴 pmd:AvoidReassigningParameters L78 L78: 避免对参数 'x' 重新赋值 建议: 在方法内使用局部变量保存 x 的初始值,并对局部变量进行递减操作,保持参数不变。
  • 🔴 pmd:SystemPrintln L181 L181: 使用了 System.out/err 输出 建议: 使用日志框架(如 java.util.logging、SLF4J、Log4j2)记录信息,便于日志管理与级别控制。
  • 🟡 pmd:AtLeastOneConstructor L9 L9: 每个类应至少声明一个构造函数 建议: 为类添加构造函数;若无需初始化逻辑,可声明一个空的包可见构造函数。
  • 🟡 pmd:DataClass L9 L9: 类 'ExternalData' 被怀疑是数据类(WOC=0.000%, NOPA=10, NOAM=0, WMC=0 建议: 将公共字段改为私有,并添加构造器与行为方法;或使用 Java record 作为不可变数据传输对象(Java 14+)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'a' 应降低可见性 建议: 将字段 a 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'b' 应降低可见性 建议: 将字段 b 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'c' 应降低可见性 建议: 将字段 c 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'd' 应降低可见性 建议: 将字段 d 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'e' 应降低可见性 建议: 将字段 e 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'f' 应降低可见性 建议: 将字段 f 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'g' 应降低可见性 建议: 将字段 g 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'h' 应降低可见性 建议: 将字段 h 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'i' 应降低可见性 建议: 将字段 i 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:PublicMemberInNonPublicType L10 L10: 非公共类型 'ExternalData' 中的公共成员 'j' 应降低可见性 建议: 将字段 j 改为 private,并对外提供必要的 getter/setter(如果确实需要访问)。
  • 🟡 pmd:AtLeastOneConstructor L14 L14: 每个类应至少声明一个构造函数 建议: 为 GodClassDemo 添加构造函数;若该类仅作为工具类,建议将构造函数设为 private 禁止实例化。
  • 🟡 pmd:GodClass L14 L14: 疑似上帝类(WMC=89, ATFD=105, TCC=0.000% 建议: 按单一职责将 GodClassDemo 拆分为多个类,将规则方法分组到不同类,并提升方法内聚性、降低对外部数据类的直接访问。
  • 🟡 pmd:MethodArgumentCouldBeFinal L16 L16: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L16 L16: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L18 L18: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L19 L19: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:MethodArgumentCouldBeFinal L22 L22: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L22 L22: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L24 L24: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L25 L25: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:MethodArgumentCouldBeFinal L28 L28: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L28 L28: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L34 L34: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L34 L34: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L46 L46: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L46 L46: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L52 L52: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:AvoidLiteralsInIfCondition L56 L56: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 x > THRESHOLD_10。
  • 🟡 pmd:MethodArgumentCouldBeFinal L61 L61: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L61 L61: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L69 L69: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L82 L82: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L82 L82: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L84 L84: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L84 L84: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:AvoidLiteralsInIfCondition L85 L85: 避免在 if 语句中使用字面量(如 3) 建议: 定义常量并替换:private static final int THRESHOLD_3 = 3; 条件改为 x > THRESHOLD_3。
  • 🟡 pmd:MethodArgumentCouldBeFinal L88 L88: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L88 L88: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L97 L97: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L97 L97: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L99 L99: 避免在 if 语句中使用字面量(如 5) 建议: 定义常量并替换:private static final int THRESHOLD_5 = 5; 条件改为 x > THRESHOLD_5。
  • 🟡 pmd:AvoidLiteralsInIfCondition L100 L100: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 x > THRESHOLD_10。
  • 🟡 pmd:MethodArgumentCouldBeFinal L103 L103: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L103 L103: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:TooFewBranchesForSwitch L106 L106: 分支少于三个的 switch 效率较低,建议改用 if 语句 建议: 将 switch (i % 2) 改为 if-elseif (i % 2 == 0) { r += d.a; } else { r += d.b; }
  • 🟡 pmd:AvoidLiteralsInIfCondition L111 L111: 避免在 if 语句中使用字面量(如 5) 建议: 定义常量并替换:private static final int THRESHOLD_5 = 5; 条件改为 x > THRESHOLD_5。
  • 🟡 pmd:MethodArgumentCouldBeFinal L114 L114: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L114 L114: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L116 L116: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L117 L117: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:MethodArgumentCouldBeFinal L120 L120: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L120 L120: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L122 L122: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L123 L123: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:MethodArgumentCouldBeFinal L126 L126: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L126 L126: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L128 L128: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L129 L129: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:MethodArgumentCouldBeFinal L132 L132: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L132 L132: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L135 L135: 避免在 if 语句中使用字面量(如 10) 建议: 定义常量并替换:private static final int THRESHOLD_10 = 10; 条件改为 i > THRESHOLD_10。
  • 🟡 pmd:AvoidLiteralsInIfCondition L135 L135: 避免在 if 语句中使用字面量(如 20) 建议: 定义常量并替换:private static final int THRESHOLD_20 = 20; 条件改为 i > THRESHOLD_20。
  • 🟡 pmd:MethodArgumentCouldBeFinal L140 L140: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L140 L140: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:AvoidLiteralsInIfCondition L142 L142: 避免在 if 语句中使用字面量(如 1) 建议: 定义常量并替换:private static final int THRESHOLD_1 = 1; 条件改为 x > THRESHOLD_1。
  • 🟡 pmd:AvoidLiteralsInIfCondition L142 L142: 避免在 if 语句中使用字面量(如 2) 建议: 定义常量并替换:private static final int THRESHOLD_2 = 2; 条件改为 x > THRESHOLD_2。
  • 🟡 pmd:AvoidLiteralsInIfCondition L143 L143: 避免在 if 语句中使用字面量(如 3) 建议: 定义常量并替换:private static final int THRESHOLD_3 = 3; 条件改为 x > THRESHOLD_3。
  • 🟡 pmd:MethodArgumentCouldBeFinal L146 L146: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L146 L146: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L152 L152: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L152 L152: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🟡 pmd:MethodArgumentCouldBeFinal L168 L168: 参数 'd' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal ExternalData d。
  • 🟡 pmd:MethodArgumentCouldBeFinal L168 L168: 参数 'x' 未被赋值,可声明为 final 建议: 将参数声明为 finalfinal int x。
  • 🔵 pmd:OneDeclarationPerLine L10 L10: 每行只声明一个变量,以增强代码可读性 建议: 将同一行的多个变量声明拆分为多行,每行一个变量。

AI 审查 · 5 条建议

  • 🟡 [AI] [bug] potential-null-dereference L16 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-if L18 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-condition L31 条件表达式恒为真 rule3L31)与 rule18L149)中的 if (x > 1 || x < 20) 对任意整数 x 均成立,导致其分支总被执行,原条件失去判断意义。 建议: 检查业务意图。如果希望同时满足两个条件,应改为 if (x > 1 && x < 20);如果确实无条件执行,应移除 if 直接执行。
  • 🔵 [AI] [design] meaningless-method-names L16 规则方法使用无意义的数字命名 rule1 到 rule20 的方法名无法描述业务行为,难以维护和理解。数字命名还暗示这些方法可能由复制粘贴生成,代码重复度高。 建议: 根据业务语义重命名方法(如 calculateDiscount、applyTax 等),并提取重复逻辑为公共方法。
  • 🔵 [AI] [performance] inefficient-nested-loop L90 rule10 存在 O(n²) 复杂度且可能产生巨大循环 rule10 使用双重 for 循环(L90-94),当 x 较大时会造成严重的性能问题;若 x 来自用户输入,可能形成拒绝服务攻击。 建议: 评估业务逻辑,避免将未受控的外部输入直接作为循环上限;考虑降低时间复杂度或增加上限校验。