SomeEnum.values() 是在无法访问的 class 或接口中定义的,当进行枚举切换时

SomeEnum.values() is defined in an inaccessible class or interface when doing switch over enum

让我们考虑基数 class:

package base;

public abstract class Base {
    protected enum BaseEnum {
        FIRST, SECOND, THIRD
    }
}

及其子class:

package a;

import base.Base;

public class A {
    // The error message appears in case when NestedA is a nested or inner class
    protected /* static */ class InnerA extends Base {
        protected BaseEnum getEnumA() {
            return BaseEnum.FIRST;
        }

        protected int xxx() {
            BaseEnum enumA = getEnumA();
            switch (enumA) {
            // ^^ base.NestedBase.BaseEnum.values() is defined in an inaccessible class or interface
                case FIRST:
                case SECOND:
                    return 1;
                default:
                    return 2;
            }
        }

        protected int xxx2() {
            BaseEnum enumA = getEnumA();
            if (enumA == BaseEnum.FIRST || enumA == BaseEnum.SECOND) {
                return 1;
            } else {
                return 2;
            }
        }

        protected int xxx3() {
            System.out.println(BaseEnum.values());
            return 2;
        }
    }
}

当我尝试编译它时,xxx() 中的 switch 语句出现编译错误:

java: base.Base.BaseEnum.values() is defined in an inaccessible class or interface

简而言之,问题是这里究竟发生了什么?为什么 values() 甚至在这里被调用?如果真的调用了,为什么访问不了?如您所见,我可以从这个 class(参见 xxx2())甚至 values() 方法(即 public 方法)正确访问 BaseEnum 及其成员InnerA superclass 中受保护的嵌套枚举,参见 xxx3())。访问计算是否如同此开关位于 A class 内一样?如果是,为什么?

这已作为错误 bugs.openjdk.java.net/browse/JDK-8178701 提出,但据我所知,Java 维护者尚未提供反馈。所以它是否被认为是一个有效的错误还不清楚。

可能的解法:

我找到的第一个解决方案是 A 必须从 Base 扩展,而不是 InnerA。因此,您可以在内部 class InnerA.

中访问受保护的 BaseEnum

第二种解决方案是简单地使 BaseEnum public.

为什么会这样?

问题出在 switch 语句上,正如您在问题中所推测的那样。但是我既没有线索也没有找到为什么 switch 语句在这个星座中通过受保护的枚举切换时会出现问题。