java - java中的枚举类型是枚举实例 "enclosed"吗?

标签 java enums jvm java-synthetic-methods

复制者:

enum IDs {
    ID {

        @Override
        void getId() {
            w(); // warning here
        }
    };

    void getId() {}

    private static void w() {}
}

发出警告:

Access to enclosing method w() from the type IDs is emulated by a synthetic accessor method

我了解什么是合成方法 - 我不明白它们如何与枚举一起发挥作用 - 我希望枚举实例具有我在枚举中定义的所有私有(private)方法。实例真的是嵌套类吗?

最佳答案

定义方法的枚举实例,如您的 ID 在这里所做的那样,是枚举类的隐式匿名子类的单例。普通访问规则适用于子类和枚举类之间,因此需要一个合成访问器来查看枚举类的私有(private)特性。

Java 语言规范 requires enums to work this way :

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...

这当然是它们的实际实现方式。在 JDK 的 javac 中,这发生在 JavacParser::enumeratorDeclaration 中。大约第 3344 行(在此版本中):

JCClassDecl body = null;
if (token.kind == LBRACE) {
    JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
    List<JCTree> defs = classOrInterfaceBody(names.empty, false);
    body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
}
if (args.isEmpty() && body == null)
    createPos = identPos;
JCIdent ident = F.at(identPos).Ident(enumName);
JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);

相关位是,如果声明中有左花括号(LBRACE),则解析类主体(classOrInterfaceBody(...) ) 用于匿名类 (names.empty),然后将其用作实例创建表达式 (NewClass(..., body)) 中的类主体。如果愿意,您可以按照 JCNewClass 节点的编译进行操作,但正如它的 javadoc 所做的那样,它足以说明它建模:

 * A new(...) operation.

如您所知,一个带有类主体的 new 操作会创建一个匿名类。

关于java - java中的枚举类型是枚举实例 "enclosed"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19465274/

相关文章:

java - GZIP Streams 的序列化/反序列化不一致

java - 如何将 way2sms 集成到我的 Android 应用程序

java - 如果使用了 waitFor,为什么杀死 JVM 也会终止其子进程?

java - 为什么不调用 doOnDispose?

java - 无法通过 java-client 连接到 Dockerized elasticsearch

c++ - C++ 中的枚举类型是跨平台的吗?

java - 如何使用 JMockit 模拟/伪造一个新的枚举值

c - C 编译器如何处理枚举?

java - 在多处理器系统中,每个处理器都会有独立的JVM吗?

java - 在 Docker 容器中运行时,JVM 无法映射保留的内存