为什么不能在方法中本地声明枚举?
今天,我发现自己编写了这样的代码……
public class LocalEnums {
public LocalEnums() {
}
public void foo() {
enum LocalEnum {
A,B,C
};
// ....
// class LocalClass { }
}
}
当编译器报告本地enum
上的错误时,我感到有点惊讶:
成员枚举 LocalEnum 不能是 本地
为什么枚举不能像类一样被声明为本地的?
我发现这在某些情况下非常有用。 在我正在工作的情况下,其余代码不需要了解有关enum
的任何信息。
是否存在任何结构/设计冲突来解释为什么这是不可能的,或者这可能是Java未来的功能?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
枚举是静态嵌套类,因为它们定义静态成员变量(枚举值),而这是不允许的内部类: http://docs.oracle.com/javase /specs/jls/se7/html/jls-8.html#jls-8.1.3
更新: 我正在查看
JLS
( java 语言规范)有关静态嵌套类的限制的更多详细信息,但没有找到它(尽管它可能在那里,隐藏在不同的主题下)。 从纯粹的实现角度来看,没有理由不能做到这一点。 所以我怀疑这是一个语言哲学问题:不应该这样做,因此不会得到支持。 但我当时并不在场,所以这纯粹是猜测。作为评论:如果您的方法足够大以至于它们需要自己的枚举,那么这是您需要重构的强烈信号。
Enums are static nested classes because they define static member variables (the enum values), and this is disallowed for inner classes: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3
Update: I was looking through the
JLS
(java language specification) for more detail on the restrictions of static nested classes, and didn't find it (although it's probably there, hidden under a different topic). From a pure implementation perspective, there's no reason that this couldn't be done. So I suspect that it was a language philosophy issue: it shouldn't be done, therefore won't be supported. But I wasn't there, so that's pure speculation.As a comment: if your methods are large enough that they require their own enums, then it's a strong sign that you need refactoring.
从 Java 16(2021-03 发布)和 Java 17(2021-09 发布)开始,其他答案已过时。
Java 16+ 中的本地枚举
作为 记录 功能的一部分,在 Java 16,枚举现在可以在本地定义。 事实上,现在记录、枚举和接口都可以是本地的。
引用 JEP 395:
您现在可以运行以下示例代码来使用方法中定义的枚举。
在此屏幕截图中,我们可以看到本地枚举如何仅存在于其定义方法中。 同级方法无法看到该枚举。 尝试从另一个方法调用该枚举会生成错误。
请参阅在 IntelliJ 中运行此类代码的演示 2020.2 IDE。
隐式
静态
本地定义的枚举有一个限制:无法访问周围类中的状态。
示例代码:
我的 IntelliJ IDE 报告错误:
正如上面的 JEP 395 引用中提到的,本地枚举是隐式静态的。 因此,您在本地枚举上定义的任何方法都无法访问周围外部类的状态。
引用 JEP 395,关于本地记录,但也适用于本地枚举:
Other Answers are outmoded as of Java 16 (released 2021-03) and Java 17 (released 2021-09).
Local enums in Java 16+
As part of the records feature introduced in Java 16, enums may now be defined locally. Indeed, records, enums, and interfaces can all be local now.
To quote JEP 395:
You can now run the following example code to use an enum defined within a method.
In this screenshot, we can see how the local enum exists only within its defining method. A sibling method cannot see that enum. Trying to call that enum from another method generates an error.
See a demo of such code running in the IntelliJ 2020.2 IDE.
Implicitly
static
There is one limitation with a locally defined enum: No access to state in surrounding class.
Example code:
My IntelliJ IDE reports error:
As mentioned in the JEP 395 quote above, a local enum is implicitly
static
. So any methods you may define on your local enum cannot access state on the surrounding outer class.To quote JEP 395, regarding local records but applying to local enums as well:
我很少发现自己在方法中编写任何类型,除非它是匿名内部类。 但是,您可以编写嵌套枚举:
我认为我真的不想读取在其中声明新类型的方法 - 您是否有任何具体原因想要在其中声明它方法而不是仅仅作为嵌套类型? 我可以看到“没有其他方法需要知道”的论点,但我认为注释可以解决这个问题,并且仍然留下更多可读的代码。
I rarely find myself writing any types within a method, unless it's an anonymous inner class. You can, however, write nested enums:
I don't think I'd really want to read a method which declared a new type within it - do you have any concrete reason for wanting to declare it inside the method instead of just as a nested type? I can see the "no other methods need to know" argument, but I think a comment can sort that out and still leave more readable code.
“嵌套枚举类型是隐式的
静态。” 8.9 枚举
它可以合理地推断
嵌套枚举类型隐式包含
静态访问修饰符。
局部类声明包含任何
以下访问之一
修饰符:公共、受保护、
私有或静态。"14.3 14.3 本地
类声明
"Nested enum types are implicitly
static." 8.9 Enums
It is reasonable to infer that
nested enum types implicitly contain
the static access modifier.
local class declaration contains any
one of the following access
modifiers: public, protected,
private, or static."14.3 14.3 Local
Class Declarations
这很奇怪,因为java内部类定义说编译时常量可以声明为静态,并且Enum的成员显然是编译时常量,加上枚举是静态类,据说......
文档:
8.1.3 内部类和封闭实例
(...) 内部类不能声明静态成员,除非它们是编译时常量字段。
It's weird because the java inner class definition says that compile-time constants can be declared static, and a member of a Enum is clearly compile-time constant, plus enum is a static class, suposedly...
Documentation:
8.1.3 Inner Classes and Enclosing Instances
(...) Inner classes may not declare static members, unless they are compile-time constant fields.
http://mindprod.com/jgloss/enum.html 给出了 Java 枚举的良好描述- 如前所述,枚举被定义为静态,因此不能将它们声明为局部变量
http://mindprod.com/jgloss/enum.html gives a good description of java enums - as previously mentioned, enums are defined as static so they can't be declared as locals