如何禁用声纳警告: 隐藏实用工具类构造函数?

我收到声纳上的警告:

隐藏实用工具类构造函数:

实用程序类不应具有 public 或缺省构造函数

我的班级:

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;
}
}

我想解决方案,以消除这个 警告声纳 Qube

191629 次浏览

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

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

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

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

如果这个类只是一个实用程序类,那么您应该使这个类成为 final 类并定义一个私有构造函数:

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

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

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

我使用一个没有实例的枚举

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.

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

例如:

/**
* 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.");
}

添加私有构造函数:

private FilePathHelper(){
super();
}

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

public class LmsEmpWfhUtils {
private LmsEmpWfhUtils()
{
// prevents access default paramater-less constructor
}
}

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

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

也就是说,将 public class FilePathHelper改为 public static class FilePathHelper

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

public class FilePathHelper
{
// private or protected constructor
// because all public fields and methods are static
private FilePathHelper() {
}
}

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

你可以使用龙目岛注释来避免不必要的初始化。

使用 @NoArgsConstructorAccessLevel.PRIVATE如下:

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FilePathHelper {
// your code
}

使用 龙目岛的替代方法是使用 @UtilityClass注释。

在龙目岛,@UtilityClass是作为一个试验性的功能推出的:

如果类是用 @UtilityClass注释的, 下面的事情发生在它身上:

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

概述:

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

此注释自动将注释类转换为一个。

不能实例化实用程序类。

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

如果该类是内部类,则该类也标记为 静电干扰

实用程序类的所有成员都自动标记为 static。 Even 字段和内部类。

例如:

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;
}
}

参考官方文件: