java - 为什么Spring Boot主应用总是触发PMD的HideUtilityClassConstructorCheck?

标签 java spring constructor spring-boot pmd

标准的 Spring Boot 应用程序有一些主要的方法类文件,比如 SampleApplication.java,看起来像这样:

@SpringBootApplication
@RestController
public class SampleApplication {

    public static void main(final String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

}

但是 PMD 静态分析将其标记为错误 (HideUtilityClassConstructorCheck):

Utility classes should not have a public or default constructor.

Makes sure that utility classes (classes that contain only static methods or fields in their API) do not have a public constructor.

Rationale: Instantiating utility classes does not make sense. Hence the constructors should either be private or (if you want to allow subclassing) protected. A common mistake is forgetting to hide the default constructor.

If you make the constructor protected you may want to consider the following constructor implementation technique to disallow instantiating subclasses:

public class StringUtils // not final to allow subclassing { protected StringUtils() { // prevents calls from subclass throw new UnsupportedOperationException(); } public static int count(char c, String s) { // ... } }

这是为什么?我应该抑制这个 PMD 错误吗?

最佳答案

检查不言而喻。

默认情况下,任何代码检查器(IntelliJ IDEA、FindBugs、PMD、Sonar)都假设如果类只有 static 方法,那么它是 utility class .实用程序类的示例是 java.lang.Math,如下所示:

public final class Math {

    /**
     * Don't let anyone instantiate this class.
     */
    private Math() {}

    public static double exp(double a) {
        ...
    }

    // More helper methods
}

这样的类被设计为将它用作静态函数包:为它声明私有(private)构造函数是一种很好的做法,因此没有人会错误地实例化它并声明类 final,因为扩展它没有意义。

在你的情况下(如果几乎每个 Spring Boot 应用程序的入口点)SampleApplication 类有一个 public static void main 方法,所以 PMD 决定它的实用类,检查私有(private)构造和最终修饰符并标记错误。这不是问题,PMD 只是不知道 Spring Boot 或任何其他框架及其入口点,因此抑制此警告并将您的类从 PMD 中排除是非常有意义的:对我来说,它在语义上比添加私有(private)构造函数更正确应用入口点。

关于java - 为什么Spring Boot主应用总是触发PMD的HideUtilityClassConstructorCheck?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37219469/

相关文章:

java - 如何在Spring Security中使用过滤器以及在过滤器中开发Authentication

java - Spring-boot 安全记住我 token 不起作用

java - 如何修复 : ON DELETE CASCADE ON UPDATE CASCADE using derby/EmbeddedDriver

java - 注释服务以使用@Retention、@Transactional、@Inherited 进行测试后,TestNG 单元测试不起作用

java - 使用JUnit测试DAO类时,无法在DB2 10.5中获得下一个序列值

java - 如何在 spring bean 中注入(inject) String 属性

c# - 在构造函数参数中和作为属性具有相似名称的变量的常见做法

c++ - Cython 和重载的 c++ 构造函数

c++ - 为什么这段代码不能编译?

java - RDF 与其他数据集互连