Menu

#912 Unnecessary Constructor - default access modifier

open
nobody
None
5
2014-08-20
2010-01-25
No

PMD 4.2.5.
PMD reports a constructor as unnecessary when it is a public, no-arg constructor with empty body or only calling super() and states: "Avoid unnecessary constructors - the compiler will generate these for you". However, the compiler generates the constructor with the same access modifier as the class - see http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.9 (for enums it generates a private constructor). So, for example, having a public, no-arg constructor with empty body in a non-public class is not a redundant declaration, but possibly an element of design. And even if not, the suggestion that the compiler will generate the "unnecessary" constructor is misleading, because the compiler will generate a constructor with different access modifier.
Samples:

=== SAMPLE 1 ===

public class Test {

public Test() {
    // useless
}

private static class TA {
    private TA() {
        // useless
    }
}

private static class TB {
    public TB() {
        // not useless - non-private constructor prevents synthetic access from the outer class
    }
}

protected static class TC {
    protected TC() {
        // useless
    }
}

}

class A {
public A() {
// not useless
}
}

class B {
B() {
// useless
}
}

=== SAMPLE 2 (from JLS, see link above) ===

package p1;
public class Outer {
protected class Inner{}
}

package p2;
class SonOfOuter extends p1.Outer {
void foo() {
new Inner(); // compile-time access error. If the Inner's class's constructor was public, the code would compile.
}
}

=========
Solution: PMD should report "Unnecessary constructor" when the constructor considered has the same access modifier as the class instead of when it is merely public.

Discussion

  • Ryan Gustafson

    Ryan Gustafson - 2010-01-25

    Thank you for the feedback. I wouldn't be surprised if this Rule predates enums in Java.

    I will try to spend some time going over your analysis, and seeing how the Rule should be modified to be most accurate.

     
  • Adam Michalik

    Adam Michalik - 2010-01-25

    Yes, in JLS ed. 1 they already say that "If the class is declared public, then the default constructor is implicitly given the access modifier public; otherwise, the default constructor has the default access implied by no access modifier" (there were no inner classes then). Anyway, enums here are just an exception from the general rule - the default constructor is always private for them as opposed to having the same access modifier as the class for "regular" classes. Thanks for looking into the problem!

     

Log in to post a comment.