自 Java 16(2021-03 发布)和 Java 17(2021-09 发布)起,其他答案已过时。
Java 16+ 中的本地枚举
作为Java 16 中引入的records 功能的一部分,现在可以在本地定义枚举。事实上,记录、枚举和接口现在都可以是本地的了。
引用 JEP 395:
引入了声明本地记录类、本地枚举类和本地接口的能力。
…
添加本地记录类是添加其他类型的隐式静态本地声明的机会。
嵌套枚举类和嵌套接口已经是隐式静态的,因此为了保持一致性,我们定义了本地枚举类和本地接口,它们也是隐式静态的。
您现在可以运行以下示例代码来使用在方法中定义的枚举。
private void demoLocalEnum ( )
{
enum Color { PURPLE, SAFETY_ORANGE }
System.out.println( Color.PURPLE );
}
在此屏幕截图中,我们可以看到本地枚举如何仅存在于其定义方法中。兄弟方法看不到该枚举。尝试从另一个方法调用该枚举会产生错误。
在IntelliJ 2020.2 IDE 中查看demo of such code running。
隐式static
本地定义的枚举有一个限制:无法访问周围类中的状态。
示例代码:
private void demoLocalEnum ()
{
int x = 42;
enum Color
{
PURPLE,
SAFETY_ORANGE;
public void demo ()
{
System.out.println( "Now is " + Instant.now() ); // This line works.
System.out.println( "x = " + x ); // ERROR — Non-static variable 'x' cannot be referenced from a static context.
}
}
Color.PURPLE.demo();
}
我的IntelliJIDE报错:
不能从静态上下文中引用非静态变量“x”
正如上面引用的 JEP 395 中提到的,本地枚举隐含地是 static。因此,您可以在本地枚举上定义的任何方法都无法访问周围外部类的状态。
引用 JEP 395,关于本地记录,但也适用于本地枚举:
本地记录类是嵌套记录类的一个特例。与嵌套记录类一样,本地记录类是隐式静态的。这意味着他们自己的方法不能访问封闭方法的任何变量;反过来,这避免了捕获立即封闭的实例,该实例会默默地将状态添加到记录类。本地记录类是隐式静态的这一事实与本地类相反,后者不是隐式静态的。事实上,局部类永远不是静态的——隐式或显式——并且总是可以访问封闭方法中的变量。