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

71 lines
5.2 KiB
Markdown

# 代码审查报告
**文件:** `data\demo-pmd\src\com\demo\bestpractices\extra\AccessorAndIpDemo.java`
**语言:** java
**耗时:** 131.2s
**分析工具:** pmd
---
总计: 17 | 错误: 3 | 警告: 13 | 建议: 1
静态分析 · 14 个问题
- 🔴 `pmd:ClassWithOnlyPrivateConstructorsShouldBeFinal` L10
该类只有私有构造函数,应声明为 final。
建议: 将类声明为 `final`,防止继承。如果类需要被实例化,应将私有构造函数改为包私有或 public。
- 🔴 `pmd:SystemPrintln` L42
使用了 `System.out/err` 输出。
建议: 在生产代码中应使用日志框架(如 SLF4J)替代 `System.out.println`。例如定义 `private static final Logger LOG = LoggerFactory.getLogger(MiscMain.class);`,并调用 `LOG.info("demo misc");`
- 🟡 `pmd:MissingStaticMethodInNonInstantiatableClass` L10
类无法被实例化,且未提供任何静态方法或静态字段。
建议: 如果该类是工具类,应声明为 final 并提供静态方法或静态字段;如果类需要实例化,则应将构造函数改为非私有。例如:声明为 `final class PrivateCtor` 并添加 `public static PrivateCtor getInstance() { return new PrivateCtor(); }`
- 🟡 `pmd:AtLeastOneConstructor` L15
每个类应至少声明一个构造函数。
建议: 为 `UsesPrivateCtor` 添加一个显式构造函数,例如 `UsesPrivateCtor() {}`
- 🟡 `pmd:CommentDefaultAccessModifier` L16
方法 `make()` 缺少默认访问修饰符的注释。
建议: 为方法添加 `/* package-private */``/* default */` 注释,明确默认的包私有访问权限。
- 🟡 `pmd:AtLeastOneConstructor` L22
每个类应至少声明一个构造函数。
建议: 为 `PrivateFieldOwner` 添加一个显式构造函数,例如 `PrivateFieldOwner() {}`
- 🟡 `pmd:ImmutableField` L23
字段 `secret` 可以声明为 final。
建议: 如果字段在初始化后不再改变,请声明为 `private final int secret = 42;`
- 🟡 `pmd:CommentDefaultAccessModifier` L24
方法 `getSecret()` 缺少默认访问修饰符的注释。
建议: 为方法添加 `/* package-private */``/* default */` 注释,明确默认的包私有访问权限。
- 🟡 `pmd:AtLeastOneConstructor` L29
每个类应至少声明一个构造函数。
建议: 为 `ReadsPrivateField` 添加一个显式构造函数,例如 `ReadsPrivateField() {}`
- 🟡 `pmd:CommentDefaultAccessModifier` L30
方法 `read(PrivateFieldOwner)` 缺少默认访问修饰符的注释。
建议: 为方法添加 `/* package-private */``/* default */` 注释,明确默认的包私有访问权限。
- 🟡 `pmd:MethodArgumentCouldBeFinal` L30
参数 `o` 未被赋值,可以声明为 final。
建议: 将参数声明为 `final PrivateFieldOwner o`,表明方法内不会重新赋值。
- 🟡 `pmd:AtLeastOneConstructor` L36
每个类应至少声明一个构造函数。
建议: 为 `HardCodedIpDemo` 添加一个显式构造函数,例如 `HardCodedIpDemo() {}`
- 🟡 `pmd:CommentDefaultAccessModifier` L37
字段 `address` 缺少默认访问修饰符的注释。
建议: 在字段声明前添加 `/* package-private */` 注释,明确访问权限。
- 🟡 `pmd:AvoidUsingHardCodedIP` L37
不要硬编码 IP 地址 `192.168.0.1`
建议: 将 IP 地址放入配置项或属性文件,在代码中通过配置读取。例如:`String address = System.getProperty("app.address", "localhost");`,如果需要使用 Spring 可用 `@Value("${app.address}")`。避免在代码中直接出现 IP 字面量。
AI 审查 · 3 条建议
- 🔴 [AI] [bug] `private-constructor-access` L17
**外部类访问私有构造函数导致编译失败**
UsesPrivateCtor.make() 中 `return new PrivateCtor();` 试图在 PrivateCtor 类外部调用其私有构造函数。根据 Java 访问控制,private 构造函数只能被声明它的类内部访问,因此该代码无法通过编译。需要将构造函数访问级别提升,或改为通过私有类提供的静态工厂方法创建实例。
建议: 将 PrivateCtor 的构造函数由 private 改为包私有(或 public),例如改为 `PrivateCtor()`;或者保留私有构造,同时在 PrivateCtor 内添加 `public static PrivateCtor getInstance()`,并将调用处改为 `PrivateCtor.getInstance()`
- 🟡 [AI] [bug] `null-check-missing` L31
**read() 未对参数进行空值检查**
ReadsPrivateField.read(PrivateFieldOwner o) 直接调用 o.getSecret()。若调用方传入 null,将抛出 NullPointerException。建议增加显式空值检查或使用 java.util.Objects.requireNonNull。
建议: 在方法开头添加 `if (o == null) { throw new NullPointerException("o"); }`;或简化为 `java.util.Objects.requireNonNull(o, "o");`
- 🔵 [AI] [design] `unused-field` L37
**字段 address 声明后从未被使用**
HardCodedIpDemo.address 字段在类中没有任何方法读取或使用它。即便移除硬编码字面量,该字段本身也可能属于无用代码。如果该字段仅用于演示规则,建议删除;如果用于配置,请提供相应的 getter 或实际使用该字段,避免维护困惑。
建议: 删除该字段(类体将保持为空),或为字段添加 getter 并在业务中使用。若采用配置注入,也应确保字段被消费。