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

问题描述 投票:4回答:2

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

@SpringBootApplication
@RestController
public class SampleApplication {

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

}

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

实用程序类不应具有公共或默认构造函数。

确保实用程序类(在其API中仅包含静态方法或字段的类)没有公共构造函数。

基本原理:实例化实用程序类没有意义。因此构造函数应该是私有的或(如果您想允许子类化)受保护。一个常见的错误是忘记隐藏默认构造函数。

如果您对构造函数进行了保护,您可能需要考虑以下构造函数实现技术来禁止实例化子类:

public class StringUtils // not final to allow subclassing {protected StringUtils(){//阻止来自子类的调用抛出new UnsupportedOperationException(); public static int count(char c,String s){// ...}}

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

java spring constructor spring-boot pmd
2个回答
1
投票

检查说明了一切。

默认情况下,任何代码检查器(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
}

这样的类被设计为使用它作为一个静态函数包:为它声明私有构造函数是一个好习惯,所以没有人会错误地实例化它并声明类final,因为扩展它是没有意义的。

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


0
投票

使用PMD规则集XML文件中的以下片段,可以仅针对具有@SpringBootApplication批注的类抑制PMD UseUtilityClass规则:

<rule ref="category/java/design.xml/UseUtilityClass">
    <properties>
        <property name="violationSuppressXPath" value="//ClassOrInterfaceDeclaration/preceding-sibling::Annotation/MarkerAnnotation/Name[@Image='SpringBootApplication']" />
    </properties>
</rule>
© www.soinside.com 2019 - 2024. All rights reserved.