JAVA枚举的嵌套_关于java:嵌套枚举是静态的吗?

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

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;

}

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

第一个错误是什么上面的问题表明B实际上属于静态类。所以在method中,它是一个静态上下文。

相反,第二个错误是,这里是一个内部类——非静态嵌套类,如Java DOC所说。

下面是我从JLS引用的一行,但它似乎有点混乱和模糊。

A nested enum type is implicitly static.

以下是匿名合成类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."":(Ljava/lang/String;ILenum_type/EnumImpl$1;)V

7: return

public void method();

Code:

0: return

}

那么B类是静态的还是非静态的?

@lew bloch似乎说的是这样的(行为与上面的枚举示例相匹配,但是如果这是真的,那么链接问题的答案在某些意义上是错误的)。

abstract class Cmp {

private int s;

static {

class Bclass extends Cmp {

public void method() {

//                System.out.println(s);

}

//            private static int b;

}

}

}

有趣的问题。我试图找到一个JLS章节,但失败(仍在寻找)。变量b上的错误很明显:具有类主体的枚举常量声明并实例化不允许静态成员的匿名类(内部类)。

更有趣的是:使用普通类(而不是枚举)也可以让method编译得很好(当然,变量b上的错误仍然存在)。

你对method()的声明是错误的。你在常量体中声明它。但它不会覆盖任何内容。它属于枚举体,而不是实例体。

实例子类型在枚举常量的静态初始值设定项中声明。因为上下文是静态的,所以它不能访问枚举实例变量。

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

常量体定义枚举的隐式嵌套匿名子类,并且不构成jls所指的嵌套枚举。每个常量都属于要声明的枚举的不同匿名子类型,而该子类型不是静态的。但是,子类型是在静态上下文中声明的,因此代码无法到达实例变量。

编辑:来自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-15.html jls-15.9.5"匿名类声明是由Java编译器从类实例创建表达式自动派生的。匿名类从不抽象(§8.1.1.1)。匿名类始终是隐式的最终类(§8.1.1.2)。匿名类始终是一个内部类(§8.1.3);它从不是静态的(§8.1.1,§8.5.1)。"

首先,我尝试让它重写一些方法:没有区别。其次,您说"它属于枚举体,而不是实例体",请显示您的引用。第三,你的回答似乎与我所联系的问题相矛盾,我应该相信谁。第四,如果它属于枚举体,为什么不能访问私有变量?

问题主要是询问枚举常量B是否是静态的。OP获取关于此主题的两条相互矛盾的错误消息。不幸的是,你的回答没有解决这个问题。

问题不在于B是否是静态的,而是"b实际上属于静态类",还是"b的类是否是静态的?"示例中唯一的枚举类型是EnumImpl,它不是静态的,也不是嵌套的。我回答的问题只有一部分是困惑。另一部分我的回答部分是指出,B声明属于内部类。为什么是静态上下文?这与method的位置不对有关,但你是对的,我没有详细解释。

试着把method移到s声明下面,看看会发生什么。

不,我不同意你的看法。如果查看字节代码,您将看到B的类不是EnumImpl。它是一个扩展EnumImpl的嵌套类。有两种枚举类型,一种是嵌套的,这是我要求的。

《捷豹路虎参考》谈到了声明。枚举声明的特殊机制为每个非平凡常量提供了一个匿名子类,是的,但这不会是隐式静态的,因为它是执行该声明的特殊机制。从你的角度来看,它是父类型的。嵌套类是在常量声明的静态上下文中定义的,因此它是静态上下文中的匿名类。匿名类不是静态的,但上下文是。无法访问声明的方法,请移动它。你是否按照建议尝试过?

看到我的编辑了吗?如果这是真的,那么我的关联问题的答案是错误的。有什么参考文献吗?

当我阅读docs.oracle.com/javase/specs/jls/se8/html/jls-8.html jls-8.9‌&8203;,链接问题中的答案是错误的。枚举常量的可选类主体隐式定义了一个匿名类声明(&167;15.9.5),该声明扩展了立即封闭的枚举类型。类主体由匿名类的常规规则控制;特别是它不能包含任何构造函数。只有当这些类实体中声明的实例方法重写封闭枚举类型(&167;8.4.8)中的可访问方法时,才可以在封闭枚举类型之外调用它们。"

Oracle、COM/JavaS/SCOS/JLS/SE8/HTML/Helip;"匿名类声明是由Java编译器从类实例创建表达式自动派生的。匿名类从不抽象(&167;8.1.1.1)。匿名类始终是隐式的final(&167;8.1.1.2)。匿名类始终是一个内部类(&167;8.1.3);它从不是静态的(&167;8.1.1,&167;8.5.1)。"

很抱歉,这么长时间没有看到您更新评论,谢谢您的参考。您可以在回答中更新这些参考:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值