Java中枚举值的可见性

Mar*_* A. 5 java enums visibility

是否有可能以某种方式将enumJava中的某些值标记为package-private,即为它们提供默认修饰符?

背景(只是为了抢占其他立即的第一条评论"为什么?";))

我有一个Task具有不同执行方法的对象和一个执行状态,它决定下一个要调用的方法.每个执行方法返回下一个要调用的方法的执行状态(基本上是执行状态机的框架).

我有一个enum包含所有可能的执行状态,但也包含一些"包内部"状态,如"挂起"或"失败",执行方法不应该返回.

我知道我可以使用自己的枚举在一个单独的变量中管理这些状态,但这会使代码变得不那么干净,因为它将单个switch语句转换为(至少)两个(并且可能是周围的if).此外,我当然可以只检查返回值,但我甚至不想在第一时间提供错误的值.

Mar*_* A. 5

听起来简单的回答是"不".

但是,考虑到不同的评论和答案(特别是Marcelo,BlackVegetable和OldCurmudgeon),我提出了以下解决方法:

包私人枚举包含所有值:

enum PackagePrivateEnum {
    PUBLIC_VALUE_1,
    PUBLIC_VALUE_2,
    PUBLIC_VALUE_3,
    PACKAGE_PRIVATE_VALUE_1,
    PACKAGE_PRIVATE_VALUE_2;
}
Run Code Online (Sandbox Code Playgroud)

第二个公共枚举仅包含公共值,并直接将这些值映射到包私有值:

public enum PublicEnum {
    PUBLIC_VALUE_1 (PackagePrivateEnum.PUBLIC_VALUE_1),
    PUBLIC_VALUE_2 (PackagePrivateEnum.PUBLIC_VALUE_2),
    PUBLIC_VALUE_3 (PackagePrivateEnum.PUBLIC_VALUE_3);

    final PackagePrivateEnum value;

    private PublicEnum(PackagePrivateEnum value) {
        this.value = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我有一个只允许返回其中一个公共值的函数,我将其定义为:

public abstract PublicEnum returnSomething();
Run Code Online (Sandbox Code Playgroud)

然后可以通过以下方式在包中使用它:

PackagePrivateEnum value = returnSomething().value;
Run Code Online (Sandbox Code Playgroud)

这隐藏了来自公众的不需要的值,并且我相信,同时最小化了包内的编码和性能开销(例如,没有switch-或if-语句,没有Map-lookups等,只.value需要一个).事实上,对于像GWT这样的智能编译器,返回值应该"内联"到甚至.value完全删除-lookup的程度,即根本没有性能开销.

此外,有了这个,可以为不同的上下文定义一个大的集合枚举的任意数量的不同允许子集:我可以很容易地定义另一个PublicEnum2暴露一组完全不同的值的子集PackagePrivateEnum.