首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么不能在方法中本地声明枚举?

为什么不能在方法中本地声明枚举?
EN

Stack Overflow用户
提问于 2009-03-31 13:02:28
回答 6查看 38.4K关注 0票数 63

今天,我发现自己编写了类似这样的代码...

代码语言:javascript
运行
复制
public class LocalEnums {

    public LocalEnums() {
    }

    public void foo() {
        enum LocalEnum {
            A,B,C
        };

        // ....
        // class LocalClass { }

    }
}

当编译器在本地enum上报告错误时,我感到有点惊讶

成员枚举LocalEnum不能是本地的

为什么不能像一样声明枚举类为本地类

我发现这在某些情况下非常有用。在我工作的情况下,其余的代码不需要知道任何关于enum的信息。

是否存在任何结构/设计冲突来解释为什么这是不可能的,或者这可能是Java的未来特性?

EN

回答 6

Stack Overflow用户

发布于 2009-03-31 13:05:28

枚举是静态嵌套类,因为它们定义了静态成员变量(枚举值),而内部类不允许这样做:http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3

更新:我在JLS (java语言规范)中查找有关静态嵌套类限制的更多细节,但没有找到(尽管它可能就在那里,隐藏在不同的主题下)。从纯实现的角度来看,没有理由不能做到这一点。所以我怀疑这是一个语言哲学问题:它不应该被做,因此不会被支持。但我不在那里,所以这纯粹是猜测。

作为注释:如果你的方法足够大,需要它们自己的枚举,那么这是一个强烈的信号,表明你需要重构。

票数 39
EN

Stack Overflow用户

发布于 2020-07-09 12:44:25

其他答案在Java 16 (发布于2021-03)和Java 17 (发布于2021-09)时已过时。

Java 16+中的本地枚举

作为Java 16中引入的records特性的一部分,枚举现在可以在本地定义。实际上,现在记录、枚举和接口都可以是本地

引用JEP 395:

引入了声明本地记录类、本地枚举类和本地接口的功能。

添加本地记录类是添加其他类型的隐式静态本地声明的机会。

嵌套的枚举类和嵌套接口已经是隐式静态的,因此为了保持一致性,我们定义了本地枚举类和本地接口,它们也是隐式静态的。

现在可以运行下面的示例代码来使用在方法中定义的枚举。

代码语言:javascript
运行
复制
private void demoLocalEnum ( )
{
    enum Color { PURPLE, SAFETY_ORANGE }
    System.out.println( Color.PURPLE );
}

在这个屏幕截图中,我们可以看到本地枚举是如何仅存在于其定义方法中的。同级方法无法看到该枚举。尝试从另一个方法调用该枚举时会产生错误。

请参阅IntelliJ 2020.2 IDE中的demo of such code running

隐式static

本地定义的枚举有一个限制:不能访问周围类中的状态。

示例代码:

代码语言:javascript
运行
复制
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();
}

My IntelliJ IDE报告错误:

不能从静态上下文引用

非静态变量'x‘

正如在上面的JEP 395引用中提到的,本地枚举隐式为static。因此,您可能在本地枚举上定义的任何方法都不能访问周围外部类上的状态。

引用JEP 395,关于本地记录,但也适用于本地枚举:

本地记录类是嵌套记录类的一种特殊情况。与嵌套的记录类一样,本地记录类也是隐式静态的。这意味着它们自己的方法不能访问封闭方法的任何变量;反过来,这又避免捕获直接封闭的实例,该实例将静默地将状态添加到record类。本地记录类是隐式静态的这一事实与本地类相反,后者不是隐式静态的。事实上,局部类从来都不是静态的--无论是隐式的还是显式的--并且总是可以访问封闭方法中的变量。

票数 16
EN

Stack Overflow用户

发布于 2009-03-31 13:06:39

我很少在一个方法中编写任何类型,除非它是一个匿名的内部类。但是,您可以编写嵌套枚举:

代码语言:javascript
运行
复制
public class NestedEnum
{
    private enum MyEnum
    {
        X, Y, Z
    }

    public void foo()
    {
    }
}

我不认为我真的想读一个在其中声明了一个新类型的方法-你有什么具体的理由想要在方法中声明它而不是仅仅作为一个嵌套类型?我可以看到“没有其他方法需要知道”的论点,但我认为注释可以解决这个问题,并仍然留下更具可读性的代码。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/700831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档