71 lines
5.2 KiB
Markdown
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 并在业务中使用。若采用配置注入,也应确保字段被消费。
|