嵌套枚举是静态的? [英] Nested enum is static?

查看:244
本文介绍了嵌套枚举是静态的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读此问题,我打开我的编辑器尝试一些代码示例来验证和理解它。以下是我的代码:

When reading this question, I open my editor to try some code samples to verify and understand it. The following is my code:

public enum EnumImpl {

    B {
        public void method() {
            System.out.println(s); //(1)non-static variable s cannot be referenced from a static context
        }
        public static int b;  //(2)Illegal static declaration in inner class
    };

    private int s;
}

但编译上面的代码让我更困惑。

But compiling the upper code makes me more confused.


  • 第一个错误来自于什么上层问题显示 B 实际上属于静态类。所以在方法中,它是一个静态上下文。

  • 相反,第二个错误说,这里是一个内部类 - 非静态嵌套类,如 java doc 说。

  • 以下是我从 JLS ,但似乎有点混乱,模糊。

  • The first error comes from what upper question shows that B actually belong to a static class. So in method, it is a static context.
  • The second error, by contrast, says that here is a inner class -- non-static nested class as java doc says.
  • The following is a line I cited from JLS, but it seems a little bit confusing and vague.

嵌套枚举类型是隐式静态的。

A nested enum type is implicitly static.


  • p>以下是B的匿名合成类的字节码:

  • The following is the byte code of anonymous synthetic class of B:

    final class enum_type.EnumImpl$1 extends enum_type.EnumImpl {
      enum_type.EnumImpl$1(java.lang.String, int);
        Code:
          0: aload_0
          1: aload_1
          2: iload_2
          3: aconst_null
          4: invokespecial #1                  // Method enum_type/EnumImpl."<init>":(Ljava/lang/String;ILenum_type/EnumImpl$1;)V
          7: return
    
      public void method();
        Code:
          0: return
    }
    


  • 所以B的类是否是静态的?

    @Lew Bloch似乎说这就像以下(行为符合上面的枚举示例,但如果这是真的,链接的问题的答案在某些意义上是错误的)。

    @Lew Bloch seems saying it is like the following (the behavior matches with above enum example, but if this is true, the answer of the linked question is wrong in some senses).

    abstract class Cmp {    
        private int s;
        static {
            class Bclass extends Cmp {
                public void method() {
    //                System.out.println(s);
                }
    //            private static int b;
            }
        }
    }
    


    推荐答案

    您的声明 method()在错误的地方。你在恒定体内声明它。但它不会覆盖任何东西。它属于枚举体,而不是实例体。

    Your declaration of method() is in the wrong place. You declare it in the constant body. But it doesn't override anything. It belongs in the enum body, not the instance body.

    实例子类型在枚举常量的静态初始化器中声明。由于上下文是静态的,因此无法访问枚举实例变量。

    The instance subtype is declared in the static initializer for the enum constant. Since the context is static it does not have access to the enum instance variables.

    您的枚举声明不是静态的,它是顶级的,顶级类不能静态。

    Your enum declaration is not static, it is top-level, and top-level classes cannot be static.

    常量体定义枚举的隐式嵌套匿名子类,并不构成JLS意义的嵌套枚举。每个常量都是您声明的枚举的不同匿名子类型,哪个子类型不是静态的。但是,子类型在静态上下文中被声明,所以这就是代码无法到达实例变量的原因。

    Constant bodies define an implicit nested anonymous subclass of the enum, and do not constitute nested enums as meant by the JLS. Each constant is of a different anonymous subtype of the enum you're declaring, which subtype is not static. However, the subtype is declared in a static context, so that's why the code can't reach the instance variable.

    编辑:JLS中有用的引用

    Useful references from the JLS

    https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.1
    可选的类体枚举常量隐式地定义了一个匿名类声明(§15.9.5),它扩展了直接包含的枚举类型,类体被匿名类的通常规则所控制,特别是不能包含任何构造函数在这些类中声明的实例方法只有当它们覆盖了包含枚举类型(§8.4.8)中的可访问方法时,才能在封闭的枚举类型之外调用这些主体。

    https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.1 "The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type. The class body is governed by the usual rules of anonymous classes; in particular it cannot contain any constructors. Instance methods declared in these class bodies may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type (§8.4.8)."

    https://docs.oracle.com/javase/specs / JLS / SE8 /热媒l / jls-15.html#jls-15.9.5
    匿名类声明由Java编译器从类实例创建表达式自动派生。一个匿名类从来不是抽象的(§8.1.1.1)。一个匿名类总是隐含的(§8.1.1.2)。一个匿名类始终是一个内部类(§8.1.3);它永远不会是静态的(§8.1.1,§8.5.1)。

    https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9.5 "An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler. An anonymous class is never abstract (§8.1.1.1). An anonymous class is always implicitly final (§8.1.1.2). An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1)."

    这篇关于嵌套枚举是静态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆