为什么枚举可以有包私有构造函数?

68

既然枚举构造函数只能被其常量调用,那么为什么它可以是包私有的?


9
为了节省代码空间并避免不必要的冗长(比如接口不需要在每个方法前加上“public abstract”),应该进行一些调整。 - ratchet freak
@ratchetfreak:这不像接口。接口方法始终是“public abstract”。明确修饰符是允许的,但没有改变它们的方法。 - Ryan Stewart
@RyanStewart 还有没有办法自己调用枚举构造函数,因此它变得逻辑上是私有的,允许包私有允许节省这些少数字符。 - ratchet freak
6
我更正了:“如果枚举类型的构造函数没有指定访问修饰符,那么该构造函数是私有的。” -- JLS 8.8.3。看起来Java教程是错误的或者至少是误导性的。 - Ryan Stewart
2个回答

105
构造函数实际上不是包私有的...它会隐式地继承 private,就像接口方法隐式地继承 public 一样,即使您没有添加关键字也是如此。
JLS 相关章节 (§8.8.3) 规定:

如果未为普通类的构造函数指定访问修饰符,则构造函数具有默认访问权限。

如果未为枚举类型的构造函数指定访问修饰符,则该构造函数为 private

如果枚举类型 (§8.9) 的构造函数声明为 publicprotected,则编译时出错。


4
引用:http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.3 - Ryan Stewart
引用的更新链接:https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.3 - Stefan Bollmann

5

这是语言的一个怪异之处:枚举构造函数默认为私有。

有趣的是,如果您声明一个包可见的枚举构造函数,就像这样:

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

    private final int i;

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

    public int getI() {
        return i;
    }
}

如果您尝试从包中的另一个类引用它,则会出现编译器错误:

无法实例化类型MyEnum


显然,你可以尝试将其设为静态嵌套类或枚举方法。是的,编译会失败,并显示该错误。 - Vlasec
2
如果您声明了一个包可见的枚举构造函数......但实际上并没有办法这样做。 - raghavsood33
@raghavsood33 是的,你可以。请查看我在答案中添加的可编译代码,它演示了一个包可见构造函数。 - Bohemian
1
你代码中的构造函数不是包私有的,而是私有的。它只是缺少一个明确的“private”关键字。如果它是一个类,那么这样做只会使它成为包私有的,但它是一个枚举,不是一个类。 - kaya3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接