-2

Using Java. The below is a single program that contains 2 methods that are called in another Class program that has the main (which proves that non-static methods require objects to be created first). HasAStaticMethod has an orange SonarLint error. Why doesn't the class NotStatic have an error, too?

public final class Test {
   private Test () {
      }
    }

class HasAStaticMethod {

    //private HasAStaticMethod(){}

    public static void myPrint(String s) {
        System.out.println(s);
    }
}

class NotStatic {

    public void myPrint(String s) {
        System.out.println(s);
    }
}```
bigwork
  • 1
  • 2
  • Your question is very unclear, but what you refer to in the title as an error is definitely not an error. It's just a hint from from your IDE. – Robby Cornelissen Mar 23 '21 at 05:16
  • 2
    And the reason for the hint is that creating an instance of `HasStaticMethod` would be a programmer mistake ... since it can serve (almost) no useful purpose. A `private` constructor would serve to flag the mistake as a compilation error. – Stephen C Mar 23 '21 at 05:19
  • 3
    See also: https://stackoverflow.com/questions/14398747, https://stackoverflow.com/questions/32375149 and so on. – Stephen C Mar 23 '21 at 05:22
  • @RobbyCornelissen I edited my question a bit for clarity. It's a pretty straightforward question, though. Yes, obviously it's a hint; I'm asking why is it there! – bigwork Mar 23 '21 at 05:34
  • @StephenC Why doesn't the class `NotStatic` have that error too then? The only difference is that the method inside it is non-static. – bigwork Mar 23 '21 at 05:36
  • 1
    Because you **need** an instance of `NoStatic` in order for call `NoStatic.myPrint`. (You don't in the `HasStaticMethod` case. Sure you could write `new HasStaticMethod().myPrint()` ... but it doesn't do what you probably think it does. The instantiation of the class is pointless, and misleading. And that is the reasoning behind the IDE hint.) – Stephen C Mar 23 '21 at 05:37
  • 2
    You are thinking about this from the wrong perspective. The goal is to write Java code that works and can be read and maintained ... by someone else. To that end, it is *good thing* when the IDE warns us we are doing something that is liable to lead to problems. – Stephen C Mar 23 '21 at 05:45
  • @StephenC You haven't answered, yet addressed, any of my questions. – bigwork Mar 23 '21 at 05:46
  • 1
    A private constructor in `NonStatic` would prevent you from using the class. Exactly because the method is non-static. No one would want that. So a SonarLint suggestion to create one would be a very bad idea. Therefore SonarLint does not suggest that. – Ole V.V. Mar 23 '21 at 06:00
  • 1
    OK. I have written you an answer. It says the same as the comments ... but ... meh. – Stephen C Mar 23 '21 at 06:08

1 Answers1

2

Why does only the class with the static method have the error: “Add a private constructor to hide the implicit public one.”?

Creating an instance of HasStaticMethod would be a programmer mistake since it can serve (almost) no useful purpose ... as well as a harmful one (see below).

Declaring a private constructor will cause that programmer mistake (i.e. mistakenly instantiating HasStaticMethod) to be flagged as a compilation error.

This is a good thing.


Why doesn't the class NotStatic have an error, too?

Because you need an instance of NoStatic in order for call NoStatic.myPrint. So you need a non-private constructor to make the instance. A default constructor will do ... because that will be public.

NoStatic.myPrint();              // compilation error
new NoStatic().myPrint();        // OK

You don't need an instance in the HasStaticMethod case. The correct way to use it is:

HasStaticMethod.myPrint();       // OK

You could write this:

new HasStaticMethod().myPrint(); // compiles ... but bad

... but it doesn't do what the reader (most likely) thinks it does. The instantiation of the class is pointless, and calling a static method via an instance reference is downright misleading. That is the reasoning behind the IDE hint: to stop the programmer (who is using your HasStaticMethod class) from accidentally or deliberately writing that kind of nonsense.


I think you may be thinking about this from the wrong perspective1. The goal is to write Java code that 1) works and 2) can be read and maintained by someone else. To that end, it is good thing when the IDE / Sonar warns us we are doing something that is liable to lead to problems. (And indeed, this is why we use tools like Sonar.)

Now you are free to twiddle with the Sonar settings to turn off this warning if you don't like it. Or stop using Sonar altogether. (But check with your coworkers and manager first, because they might have some opinions on that course of action.)

But my advice is to just add the private constructor and declare the utility class as final ... as Sonar suggests. It is (IMO) a good thing to do.


1 - This should not be about "freedom of expression" or "personal choice". This is not poetry ...

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216