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

Posted

技术标签:

【中文标题】为啥枚举可以有包私有构造函数?【英文标题】:Why can a enum have a package-private constructor?为什么枚举可以有包私有构造函数? 【发布时间】:2011-12-06 13:42:23 【问题描述】:

既然枚举构造函数只能被它的常量调用,那为什么还允许它是包私有的呢?

【问题讨论】:

允许节省一点代码空间并避免不必要的冗长(就像接口在每个方法之前都不需要public abstract @ratchetfreak:它不像接口。接口方法总是public abstract。允许显式修改修饰符,但无法更改它们。 @RyanStewart 也没有办法自己调用枚举构造函数,因此它在逻辑上变得私有,并且允许包私有允许保存这几个字符 我更正了:“如果没有为枚举类型的构造函数指定访问修饰符,则构造函数是私有的。” --JLS 8.8.3。看来 java 教程不正确或至少具有误导性。 【参考方案1】:

构造函数实际上不是包私有的......它隐含的private 接口方法隐含的public,即使你不添加关键字。

JLS (§8.8.3) 的相关部分指出:

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

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

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

【讨论】:

引用:java.sun.com/docs/books/jls/third_edition/html/…【参考方案2】:

这是语言的一个怪癖:枚举构造函数是隐式私有的。

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

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

    private final int i;

    MyEnum(int i) 
        this.i = i;
    

    public int getI() 
        return i;
    

您不能从包中的另一个类中引用它。如果你尝试,你会得到编译器错误:

无法实例化类型 MyEnum

【讨论】:

显然你可以尝试使用枚举作为静态嵌套类或枚举的方法。是的,编译失败并出现上述错误。 "如果你声明了一个包可见的枚举构造函数"...但实际上没有办法做到这一点。 @raghavsood33 是的,你可以。请参阅我添加到答案中的可编译代码,该代码演示了包可见的构造函数。 代码中的构造函数不是包私有的;它是私人的。它只是缺少一个明确的private 关键字。如果它是一个类,那只会使它成为包私有,但它是一个枚举,而不是一个类。

以上是关于为啥枚举可以有包私有构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要私有构造函数?

如果构造函数在私有部分,为啥我们不能创建对象?

为啥枚举的构造函数不能访问静态字段?

为啥具有私有构造函数的类不阻止从此类继承?如何控制哪些类可以从某个基类继承?

为啥 GCC 在匹配函数时会查看私有构造函数?

为啥私有构造函数在案例类中仍然可见?