123

我在声纳上收到此警告。我想要解决方案来删除 Sonar Qube 上的这个警告。

我的课是这样的:

public class FilePathHelper {
    private static String resourcesPath;
    public static String getFilePath(HttpServletRequest request) {
        if(resourcesPath == null) {
            String serverpath = request.getSession().getServletContext().getRealPath("");               
            resourcesPath = serverpath + "/WEB-INF/classes/";   
        }
        return resourcesPath;       
    }
}

我想要适当的解决方案来消除声纳上的这个警告。

4

11 回答 11

222

如果这个类只是一个实用类,你应该将这个类设为 final 并定义一个私有构造函数:

public final class FilePathHelper {
   private FilePathHelper() {
      //not called
   }
}

这可以防止在代码的其他地方使用默认的无参数构造函数。

此外,您可以将类设为 final,这样它就不能在子类中扩展,这是实用程序类的最佳实践。由于您只声明了一个私有构造函数,因此其他类无论如何都无法扩展它,但将类标记为 final 仍然是最佳实践。

于 2013-01-18T12:16:05.950 回答
21

我不知道声纳,但我怀疑它正在寻找一个私有构造函数:

private FilePathHelper() {
    // No-op; won't be called
}

否则,Java 编译器将提供一个公共的无参数构造函数,这是您不想要的。

(您还应该使类成为最终类,尽管其他类无论如何都无法扩展它,因为它只有一个私有构造函数。)

于 2013-01-18T12:15:57.323 回答
12

我使用没有实例的枚举

public enum MyUtils { 
    ; // no instances
    // class is final and the constructor is private

    public static int myUtilityMethod(int x) {
        return x * x;
    }
}

您可以使用

int y = MyUtils.myUtilityMethod(5); // returns 25.
于 2013-01-18T12:37:55.430 回答
10

最佳实践是在构造类时抛出错误。

例子:

/**
 * The Class FooUtilityService.
 */
final class FooUtilityService{

/**
* Instantiates a new FooUtilityService. Private to prevent instantiation
*/
private FooUtilityService() {

    // Throw an exception if this ever *is* called
    throw new AssertionError("Instantiating utility class.");
}
于 2015-01-15T18:35:07.957 回答
7

您可以只使用 Lombok 注释来避免不必要的初始化。

使用@NoArgsConstructor如下AccessLevel.PRIVATE

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FilePathHelper {
   // your code 
}
于 2020-06-16T12:35:18.150 回答
1

我建议在 Sonar 中禁用此规则,引入私有构造函数并没有真正的好处,只是代码库中的冗余字符需要其他人阅读并且计算机需要存储和处理。

于 2020-04-21T19:40:45.023 回答
0

使用Lombok的替代方法是使用@UtilityClass注释。

@UtilityClass在 Lombok 中作为实验性功能引入v1.16.2

如果一个类用 注释@UtilityClass,它会发生以下事情:

  • 它被标记为最终。
  • 如果在其中声明了任何构造函数,则会生成错误。
    • 否则,将生成一个私有的无参数构造函数;它抛出一个.UnsupportedOperationException
  • 类中的所有方法、内部类和字段都被标记 static

概述:

实用程序类是一个只是函数命名空间的类。它的任何实例都不能存在,并且它的所有成员都是静态的。例如,java.lang.Mathjava.util.Collections是众所周知的实用程序类。

这个注解会自动将被注解的类变成一个类。

不能实例化实用程序类。

通过用 标记您的类@UtilityClasslombok 将自动生成一个引发异常的私有构造函数,将您添加的任何显式构造函数标记为错误,并将类标记为 final。

如果该类是内部类,则该类也被标记为static

实用程序类的所有成员都自动标记为静态。甚至字段和内部类。

例子:

import lombok.experimental.UtilityClass;

@UtilityClass
public class FilePathHelper {

    private static String resourcesPath;

    public static String getFilePath(HttpServletRequest request) {
        if(resourcesPath == null) {
            ServletContext context = request.getSession().getServletContext();
            String serverpath = context.getRealPath("");               
            resourcesPath = serverpath + "/WEB-INF/classes/";   
        }
        return resourcesPath;       
    }
}

来自官方文档的参考:

于 2022-02-17T23:36:49.090 回答
-1

SonarQube 文档建议static在类声明中添加关键字。

即更改public class FilePathHelperpublic static class FilePathHelper.

或者,您可以添加私有或受保护的构造函数。

public class FilePathHelper
{
    // private or protected constructor
    // because all public fields and methods are static
    private FilePathHelper() {
    }
}
于 2018-12-17T18:01:47.040 回答
-1
public class LmsEmpWfhUtils {    
    private LmsEmpWfhUtils() 
    { 
    // prevents access default paramater-less constructor
    }
}

这可以防止在代码的其他地方使用默认的无参数构造函数。

于 2018-05-24T06:40:13.160 回答
-1

添加私有构造函数:

private FilePathHelper(){
    super();
}
于 2016-05-04T04:59:20.080 回答
-3

使实用程序类最终并添加一个私有构造函数

于 2018-04-19T00:05:27.030 回答