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

时间:2016-05-13 21:17:34

标签: 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):

  

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

     

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

     

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

     

如果你使构造函数受到保护,你可能需要考虑   以下构造函数实现技术禁止   实例化子类:

     

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

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

4 个答案:

答案 0 :(得分: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之外是完全合理的:对我而言,它更加语义化比将私有构造函数添加到应用程序入口点更正确。

答案 1 :(得分: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>

答案 2 :(得分:0)

您可以使用@SuppressWarnings("PMD")在进入点中禁止显示警告,因为Spring Core使用基于反射和PMD分析器无法分析的其他内容的面向方面的编程。不用担心在此类中禁止显示警告

对于eaxmple:

@SuppressWarnings("PMD")
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@EnableScheduling
@EnableConfigurationProperties
public class Application {

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

}

您可以在此处了解更多信息:https://pmd.github.io/latest/pmd_userdocs_suppressing_warnings.html

答案 3 :(得分:0)

现在,您可以像这样忽略注释Network.HTTP.Client.Conduit.httpLBS

@SpringBootApplication

请参见UseUtilityClassPMD 6.16.0 (30-June-2019)