Java对继承自父类的枚举做switch时报values()为不可访问问题
问题解答
1. switch语句隐式调用枚举values()方法的原因
Java编译器处理枚举类型的switch语句时,会自动生成一个名为$SwitchMap的静态映射数组,用来关联枚举实例的ordinal(序数值)和switch分支的跳转位置,提升switch执行效率。初始化这个数组时,需要通过values()方法拿到该枚举的所有实例,遍历每个实例的ordinal填充映射表,所以会隐式调用枚举的values()方法。
2. 显式调用正常、switch隐式调用无权限的原因
BaseEnum是Base类的protected嵌套枚举,按照Java访问权限规则,protected成员仅允许同包类、子类访问:
- 你写的
xxx2()、xxx3()方法都定义在InnerA类中,InnerA是Base的子类,符合protected访问规则,所以可以正常访问BaseEnum的成员和values()方法。 - switch隐式调用
values()的代码是编译器自动生成的辅助代码,这段代码不会被放到InnerA类中,而是会被放到最外层的A类中。A本身既不和Base同包,也不是Base的子类,没有权限访问Base的protected成员BaseEnum,所以编译时会报访问权限错误。
3. 访问权限判定是否视为在外部类A执行
是的,这个判定符合javac的编译实现逻辑:枚举switch的辅助映射代码默认生成在顶层外部类的作用域下,所以权限校验会按照外部类A的上下文来执行,而不是按照内部类InnerA的上下文。
内容的提问来源于stack exchange,提问作者Kirill Gagarski
相关产品推荐
相关产品推荐

