Oomph Fortuity
Oomph Fortuity

Reputation: 6118

How to disable warning on Sonar: Hide Utility Class Constructor?

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

Answers (12)

Py_Patience
Py_Patience

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 -

  1. Remove @UtilityClass and make it static final class with private constructor.
  2. Instead of using it as class, Use it as Enum . but -

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.

Overview:

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.

Example:

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

RoflcoptrException
RoflcoptrException

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

Roman Topalov
Roman Topalov

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

Jon Skeet
Jon Skeet

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

user431640
user431640

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

pamcevoy
pamcevoy

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

Rinku Gohel
Rinku Gohel

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

Amit Agrawal
Amit Agrawal

Reputation: 1

make the utility class final and add a private constructor

Upvotes: -3

chethan s j
chethan s j

Reputation: 9

Add private constructor:

private FilePathHelper(){
    super();
}

Upvotes: -1

Peter Lawrey
Peter Lawrey

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

javaPlease42
javaPlease42

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

Related Questions