当前位置: 首页 > 知识库问答 >
问题:

为什么枚举中的静态和实例init块的行为与类中的不同

许典
2023-03-14
    null

谢谢!这让我很困惑。

public class EnumInit {
public static void main(String[] args) {
    System.out.println(Color.RED.toString() + " Main");
    MyInit myInit = new MyInit();
    System.out.println(Color.BLUE.toString() + " Main");
    MyInit mySecondInit = new MyInit();

}
}

enum Color {    
RED, BLUE, GREEN;
String instanceVar = "Enum Instance Variable Text";
static { System.out.println("Enum Static init block 1"); }
{ System.out.println("Enum Instance init block 1"); }
static { System.out.println("Enum Static static init block 2"); }
Color() { 
    System.out.println(instanceVar);
    System.out.println("Enum String Literal"); 
}
{ System.out.println("Enum Instance init block 2"); }   
}

class MyInit {
String instanceVar = "Class Instance Variable Text";
static { System.out.println("Class Static init block 1"); }
{ System.out.println("Class Instance init block 1"); }
static { System.out.println("Class Static static init block 2"); }
MyInit() { 
    System.out.println(instanceVar);
    System.out.println("Class String Literal"); 
}
{ System.out.println("Class Instance init block 2"); }  
}

共有1个答案

丌官哲彦
2023-03-14

Java语言规范对enum常量是这样说的

除了枚举类型E从枚举继承的成员之外,对于每个名为n的已声明的枚举常量,枚举类型都有一个隐式声明的名为n的类型E的公共静态final字段。这些字段被认为是按照与相应的枚举常量相同的顺序声明的,在枚举类型中显式声明的任何静态字段之前。每个这样的字段都被初始化为对应于它的枚举常量。

所以

enum Color {    
    RED, BLUE, GREEN;
    ...
}
public static final Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();

见上文。

枚举可以有实例初始化块吗?

是的,编译你的代码,你就会看到。

Color color = Color.RED;
 类似资料:
  • 问题内容: 我已经了解到,在Java中,静态类在初始化类时执行,实例块在构造类的每个实例之前执行。我一直看到静态块要在实例块之前执行。为什么情况相反呢? 谁能解释一下示例代码的输出: 输出: 实例块 8 实例块 10 实例块 12 实例块 20 静态块 问题答案: 您需要知道枚举值是保存该枚举类型实例的静态字段,并且静态字段的初始化顺序取决于它们的位置。看这个例子 输出 现在,由于枚举值始终放在枚

  • 问题内容: 这来自有效的Java: 请注意,操作常量是从创建常量之后运行的静态块放入stringToEnum映射中的。试图使每个常量从其自己的构造函数中放入映射中将导致编译错误。这是一件好事,因为如果合法,它将导致NullPointerException。除编译时常量字段外,不允许枚举构造函数访问枚举的静态字段。此限制是必需的,因为在构造函数运行时尚未初始化这些静态字段。 我的问题是关于这条线的:

  • 这是我的代码: 还有我的测试,我单独运行。 当我运行test foo时,我将看到: 但是当我运行测试栏时,我看到的是: 引用本页内容。。 类对象由Java虚拟机在加载类时自动构造,并通过调用类加载器中的defineClass方法来构造。 所以我的理解是,在测试条中,愚蠢的类被加载,否则我会看到一个空的,我猜?所以类对象被创建,因为类本身被加载。。 现在引用这一页 静态初始化块在JVM(类加载器-具

  • 问题内容: 这是代码 我期望的输出是: 但实际上是: 看来Child类中的静态块没有得到执行,但是为什么呢?这是反直觉的,不是吗? 补充: 为了更清楚,我列出了 2 __以下 1 分: 正如@axtavt所说,根据JLS 12.4.1,类Child已加载,但未初始化。 但是@Alexei Kaigorodov指出,根据 jvms-5.5,应初始化Child类,因为对Child类执行了getstat

  • 问题内容: Java中的静态和非静态枚举有什么区别?两种用法是相同的。 正确吗 所有静态的都在启动时加载到内存中,非静态的则按需加载 ? 如果是,那么哪种方法更好?将某些数据始终保留在内存中还是每次使用服务器资源加载它们? 问题答案: 所有的都是有效的。如果您有嵌套的枚举,则它与相同。 所有类都是延迟加载的(枚举或其他),但是在加载时,它们会一次全部加载。也就是说,您不能加载一些常量,而不能加载其

  • 我想为任何枚举对象创建通用方法,它将检查枚举是否具有指定的值名称,但作为类型对象,我无法使用方法。为什么? 有没有办法从类型对象中获取值? 我需要这样的方法来检查配置中的值是否是myEnum的有效字符串。valueOf(字符串) 因为如果给定的字符串错误,那么它将抛出一个异常(我不想要它)。 我希望我的方法如下所示: 但是没有方法,如何正确创建这个方法?