Reputation: 6118
I'm getting this warning on Sonar:
Hide Utility Class Constructor:
Utility classes should not have a public or default constructor
My class:
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;
}
}
I want solution to remove this warning on Sonar Qube.
Upvotes: 142
Views: 221687
Reputation: 41
Although using @UtilityClass annotation will show issue on sonarCube. So basic problem is "Java provide a default no-argument public constructor" for a class. now we have two solutions -
When the problem in sonarQube then use -
@SuppressWarnings("java:###")
"###" rule number.
Upvotes: 1
Reputation: 5326
Alternative using Lombok is use @UtilityClass
annotation.
@UtilityClass
was introduced as an experimental feature in Lombok v1.16.2
:
If a class is annotated with
@UtilityClass
, the following things happen to it:
- It is marked final.
- If any constructors are declared in it, an error is generated.
- Otherwise, a private no-args constructor is generated; it throws a
UnsupportedOperationException
.- All methods, inner classes, and fields in the class are marked
static
.
A utility class is a class that is just a namespace for functions. No instances of it can exist, and all its members are static. For example, java.lang.Math
and java.util.Collections
are well known utility classes.
This annotation automatically turns the annotated class into one.
A utility class cannot be instantiated.
By marking your class with @UtilityClass
, lombok will automatically generate a private constructor that throws an exception, flags as error any explicit constructors you add, and marks the class final.
If the class is an inner class, the class is also marked static.
All members of a utility class are automatically marked as static. Even fields and inner classes.
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;
}
}
Reference from official documentation:
Upvotes: 3
Reputation: 52239
If this class is only a utility class, you should make the class final and define a private constructor:
public final class FilePathHelper {
private FilePathHelper() {
//not called
}
}
This prevents the default parameter-less constructor from being used elsewhere in your code.
Additionally, you can make the class final, so that it can't be extended in subclasses, which is a best practice for utility classes. Since you declared only a private constructor, other classes wouldn't be able to extend it anyway, but it is still a best practice to mark the class as final.
Upvotes: 252
Reputation: 101
You can just use Lombok annotation to avoid unnecessary initialization.
Using @NoArgsConstructor
with AccessLevel.PRIVATE
as bellow:
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FilePathHelper {
// your code
}
Upvotes: 10
Reputation: 1500983
I don't know Sonar, but I suspect it's looking for a private constructor:
private FilePathHelper() {
// No-op; won't be called
}
Otherwise the Java compiler will provide a public parameterless constructor, which you really don't want.
(You should also make the class final, although other classes wouldn't be able to extend it anyway due to it only having a private constructor.)
Upvotes: 22
Reputation: 61
I recommend just disabling this rule in Sonar, there is no real benefit of introducing a private constructor, just redundant characters in your codebase other people need to read and computer needs to store and process.
Upvotes: 4
Reputation: 1246
SonarQube documentation recommends adding static
keyword to the class declaration.
That is, change public class FilePathHelper
to public static class FilePathHelper
.
Alternatively you can add a private or protected constructor.
public class FilePathHelper
{
// private or protected constructor
// because all public fields and methods are static
private FilePathHelper() {
}
}
Upvotes: -1
Reputation: 24
public class LmsEmpWfhUtils {
private LmsEmpWfhUtils()
{
// prevents access default paramater-less constructor
}
}
This prevents the default parameter-less constructor from being used elsewhere in your code.
Upvotes: -1
Reputation: 533550
I use an enum with no instances
public enum MyUtils {
; // no instances
// class is final and the constructor is private
public static int myUtilityMethod(int x) {
return x * x;
}
}
you can call this using
int y = MyUtils.myUtilityMethod(5); // returns 25.
Upvotes: 12
Reputation: 4963
Best practice is to throw an error if the class is constructed.
Example:
/**
* 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.");
}
Upvotes: 10