Why can a enum have a package-private constructor?
Asked Answered
L

2

70

Since an enum constructor can only be invoked by its constants, why is it then allowed to be package-private?

Landlady answered 12/10, 2011 at 23:57 Comment(4)
to allow to save a bit on code space and to avoid needless verbosity (like interfaces don't need public abstract before every method)Centrifuge
@ratchetfreak: It's not like interfaces. Interface methods are always public abstract. Making the modifiers explicit is allowed, but there's no way to change them.Reredos
@RyanStewart there's also no way to call a enum constructor yourself so it becomes logically private and allowing package private allows saving those few charsCentrifuge
I stand corrected: "If no access modifier is specified for the constructor of an enum type, the constructor is private." -- JLS 8.8.3. It seems the java tutorial is incorrect or at least misleading.Reredos
K
106

The constructor actually isn't package-private... it's implicitly private the way interface methods are implicitly public even if you don't add the keyword.

The relevant section of the JLS (§8.8.3) states:

If no access modifier is specified for the constructor of a normal class, the constructor has default access.

If no access modifier is specified for the constructor of an enum type, the constructor is private.

It is a compile-time error if the constructor of an enum type (§8.9) is declared public or protected.

Knuth answered 13/10, 2011 at 0:44 Comment(2)
citation: java.sun.com/docs/books/jls/third_edition/html/…Reredos
Updated link for citation: docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.3Izy
P
5

It's a quirk of the language: enum constructors are implicitly private.

Interestingly, if you declare a package-visible enum constructor, like this:

public enum MyEnum {
    A(0),
    B(1);

    private final int i;

    MyEnum(int i) {
        this.i = i;
    }

    public int getI() {
        return i;
    }
}

you can't refer to it from another class in the package. If you try, you get the compiler error:

Cannot instantiate the type MyEnum

Pentha answered 13/10, 2011 at 2:1 Comment(4)
Apparently you can try this with enum being static nested class or in a method of the enum. Yes, compilation fails with said error.Gen
"if you declare a package-visible enum constructor"...but actually there is no way to do that.Centre
@Centre yes you can. See the compilable code I added to my answer that demonstrates a package-visible constructor.Pentha
The constructor in your code is not package-private; it is private. It just lacks an explicit private keyword. That would only make it package-private if it were a class, but it is an enum, not a class.Peasant

© 2022 - 2024 — McMap. All rights reserved.