[Java:S2333] False positive for enum constructors

The code below triggers the S2333 rule with the message "private" is redundant in this context.

According to Oracle, “The constructor for an enum type must be package-private or private access”, So, in this case, privateis not redundant; if it is not used, the enum constructor be would package private, which is not what is wanted.

Versions used: SonarQube 7.9.2, scanner 4.4.0, Java plugin 6.3.2

    public enum Axis {
        X("X axis"),
        Y("Y axis"),
        Z("Z axis");

        private final String text;
        
        private Axis(String s) { this.text = s; }
        public String getLabel()  { return text; }
    }

Hello @Philippe_Couton

The end of the note you are referring to states that:

You cannot invoke an enum constructor yourself.

So anyway, it seems that you cannot do what you try to prevent (using this constructor somewhere else).

In addition, JLS 8.9.2 states that:

In an enum declaration, a constructor declaration with no access modifiers is private.

This is why S2333 suggest that you can safely remove it.

Hope it makes sense.

Best,
Quentin

The JLS section you refer to is for Java 8. In JLS for Java 7, there is no such statement. And not everyone has switched to Java 8 or a more recent version; in my case, this is not my choice.

Anyway, there is something strange in the Java 8 version of JLS :

  • JLS states that " It is a compile-time error if a constructor declaration of an enum type is public or protected", so it can only be private or package-protected.
  • If the constructor has a “private” access modifier or no access modifier at all, it will be private. So, knowing that it can be package-protected, how would you declare a such constructor ?

Enums are not designed to be instantiated. And in fact, you can not instantiate them, trying to do this will result in a compile-time error: enum types may not be instantiated. I tried with Java 7 and the error is the same.

So in the end, private or no (package protected) modifier is just a question of what is accepted or not by the grammar, not about setting access visibility.

I made a little bit of introspection, and the constructor is private, with or without the private keyword, in Java 7 and Java 8. So, I agree with you, an enum can’t be instantiated explicitely, and the private keyword is only a grammar point.

Thanks for your clarification

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.