今天,我发现自己编写了这样的代码......
public class LocalEnums {
public LocalEnums() {
}
public void foo() {
enum LocalEnum {
A,B,C
};
// ....
// class LocalClass { }
}
}
Run Code Online (Sandbox Code Playgroud)
当编译器报告本地错误时,我有点惊讶enum:
成员枚举LocalEnum不能是本地的
为什么枚举不能像类一样在本地声明?
我发现这在某些情况下非常有用.在我工作的情况下,其余的代码不需要知道任何关于enum.
是否有任何结构/设计冲突可以解释为什么这是不可能的,或者这可能是Java 的未来特性?
kdg*_*ory 38
枚举是静态嵌套类,因为它们定义静态成员变量(枚举值),这对于内部类是不允许的:http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html #JLS-8.1.3
更新:我正在查看JLS(java语言规范)以获取有关静态嵌套类限制的更多详细信息,并且没有找到它(尽管它可能存在,隐藏在不同的主题下).从纯粹的实现角度来看,没有理由不这样做.所以我怀疑这是一个语言哲学问题:不应该这样做,因此不会得到支持.但我不在那里,所以这是纯粹的猜测.
作为评论:如果你的方法足够大,他们需要自己的枚举,那么这是一个强烈的迹象,你需要重构.
Jon*_*eet 15
我很少发现自己在一个方法中编写任何类型,除非它是一个匿名的内部类.但是,您可以编写嵌套枚举:
public class NestedEnum
{
private enum MyEnum
{
X, Y, Z
}
public void foo()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我不认为我真的想读一个在其中声明一个新类型的方法 - 你是否有任何具体的理由想要在方法中声明它而不仅仅是一个嵌套类型?我可以看到"没有其他方法需要知道"的论点,但我认为评论可以对此进行排序,并且仍然保留更多可读代码.
Bas*_*que 14
从 2021 年 3 月 16 日发布的 Java 16 开始,其他答案已经过时。
作为Java 16 中新记录功能的一部分,现在可以在本地定义枚举。事实上,记录、枚举和接口现在都可以是本地的。
引用 JEP 395:
引入了声明本地记录类、本地枚举类和本地接口的能力。
…
添加本地记录类是添加其他类型的隐式静态本地声明的机会。
嵌套的枚举类和嵌套的接口已经是隐式静态的,所以为了保持一致性,我们定义了本地枚举类和本地接口,它们也是隐式静态的。
您现在可以运行以下示例代码以使用在方法中定义的枚举。
private void demoLocalEnum ( )
{
enum Color { PURPLE, SAFETY_ORANGE }
System.out.println( Color.PURPLE );
}
Run Code Online (Sandbox Code Playgroud)
在此屏幕截图中,我们可以看到本地枚举如何仅存在于其定义方法中。同级方法无法看到该枚举。尝试从另一个方法调用该枚举会产生错误。
查看在IntelliJ 2020.2 IDE 中运行的此类代码的演示。
static本地定义的枚举有一个限制:无法访问周围类中的状态。
示例代码:
private void demoLocalEnum ( )
{
enum Color { PURPLE, SAFETY_ORANGE }
System.out.println( Color.PURPLE );
}
Run Code Online (Sandbox Code Playgroud)
不能从静态上下文中引用非静态变量“x”
正如上面 JEP 395 引用中提到的,本地枚举是隐式的static。因此,您在本地枚举上定义的任何方法都无法访问周围外部类的状态。
引用 JEP 395,关于本地记录,但也适用于本地枚举:
本地记录类是嵌套记录类的一种特殊情况。与嵌套记录类一样,本地记录类是隐式静态的。这意味着它们自己的方法不能访问封闭方法的任何变量;反过来,这避免了捕获一个立即封闭的实例,该实例会默默地向记录类添加状态。本地记录类是隐式静态的事实与本地类相反,本地类不是隐式静态的。事实上,局部类从来都不是静态的——隐式或显式——并且总是可以访问封闭方法中的变量。
emo*_*ory 10
"嵌套的枚举类型是隐式静态的." 8.9枚词
推断嵌套枚举类型隐式包含静态访问修饰符是合理的.
| 归档时间: |
|
| 查看次数: |
32500 次 |
| 最近记录: |