今天,我发现自己编写了类似这样的代码...
public class LocalEnums {
public LocalEnums() {
}
public void foo() {
enum LocalEnum {
A,B,C
};
// ....
// class LocalClass { }
}
}
当编译器在本地enum
上报告错误时,我感到有点惊讶
成员枚举LocalEnum不能是本地的
为什么不能像类一样声明枚举类为本地类
我发现这在某些情况下非常有用。在我工作的情况下,其余的代码不需要知道任何关于enum
的信息。
是否存在任何结构/设计冲突来解释为什么这是不可能的,或者这可能是Java的未来特性?
发布于 2009-03-31 13:05:28
枚举是静态嵌套类,因为它们定义了静态成员变量(枚举值),而内部类不允许这样做:http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3
更新:我在JLS
(java语言规范)中查找有关静态嵌套类限制的更多细节,但没有找到(尽管它可能就在那里,隐藏在不同的主题下)。从纯实现的角度来看,没有理由不能做到这一点。所以我怀疑这是一个语言哲学问题:它不应该被做,因此不会被支持。但我不在那里,所以这纯粹是猜测。
作为注释:如果你的方法足够大,需要它们自己的枚举,那么这是一个强烈的信号,表明你需要重构。
发布于 2020-07-09 12:44:25
其他答案在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();
}
不能从静态上下文引用
非静态变量'x‘
正如在上面的JEP 395引用中提到的,本地枚举隐式为static
。因此,您可能在本地枚举上定义的任何方法都不能访问周围外部类上的状态。
引用JEP 395,关于本地记录,但也适用于本地枚举:
本地记录类是嵌套记录类的一种特殊情况。与嵌套的记录类一样,本地记录类也是隐式静态的。这意味着它们自己的方法不能访问封闭方法的任何变量;反过来,这又避免捕获直接封闭的实例,该实例将静默地将状态添加到record类。本地记录类是隐式静态的这一事实与本地类相反,后者不是隐式静态的。事实上,局部类从来都不是静态的--无论是隐式的还是显式的--并且总是可以访问封闭方法中的变量。
发布于 2009-03-31 13:06:39
我很少在一个方法中编写任何类型,除非它是一个匿名的内部类。但是,您可以编写嵌套枚举:
public class NestedEnum
{
private enum MyEnum
{
X, Y, Z
}
public void foo()
{
}
}
我不认为我真的想读一个在其中声明了一个新类型的方法-你有什么具体的理由想要在方法中声明它而不是仅仅作为一个嵌套类型?我可以看到“没有其他方法需要知道”的论点,但我认为注释可以解决这个问题,并仍然留下更具可读性的代码。
https://stackoverflow.com/questions/700831
复制相似问题