繁体   English   中英

Java枚举实例的生命周期

[英]Life span of a Java enum instance

据我所知,每个枚举类型的预定义常量只有一个实例。 那是对的吗? 现在,假设存在一个名为enum的value的实例变量,并假设ONE是预定义的常量。 如果value被修改的(的)实例ONE那么这将影响指的是所有的变量ONE 但是当垃圾收集器摆脱枚举的所有实例时,值的value会发生什么? 他们甚至被扔掉了吗?

这是一个简单的例子,其中有两个变量AB ,都指的是ONE 在第一次使用B之前,值的value被否定。 如果垃圾收集器在Number B = Number.ONE;Number B = Number.ONE;之前删除了ONE的实例Number B = Number.ONE; 那么我猜想,价值的value会被“重置”回到1。 它是否正确?

枚举:

public enum Number
{
    ONE(1), TWO(2), THREE(3); 

    int value;

    Number(int value) { this.value = value; }

    void negate() { value = -value; }

    @Override
    public String toString() { return "value: " + value; }
}

主要方法:

public static void main(String[] args)
{
    Number A = Number.ONE;
    A.negate();
    Number B = Number.ONE;

    System.out.println(A + "   " + B);
}

输出:

值:-1值:-1

所以我的问题是,输出是否可以如下(如果说A = null;在使用B之前添加)?

值:-1值:1

枚举是隐式public static final字段,因此它们永远不会被垃圾回收。

编辑

正如@RealSkeptic在评论中所指出的那样,在具有多个类加载器的jvm实例中,事情有点复杂。 然后静态字段值可能会在卸载类时消失

但是,默认情况下,只要jvm实例处于活动状态,就只有一个类加载器处于活动状态,因此在您的示例应用程序中,静态字段不会被垃圾收集。

对于这个枚举:

public enum FooEnum {
  CONST
}

生成此字节代码:

Compiled from "FooEnum.java"
public final class FooEnum extends java.lang.Enum<FooEnum> {
  public static final FooEnum CONST;

  static {};
    Code:
       0: new           #1                  // class FooEnum
       3: dup
       4: ldc           #12                 // String CONST
       6: iconst_0
       7: invokespecial #13                 // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #17                 // Field CONST:LFooEnum;
      13: iconst_1
      14: anewarray     #1                  // class FooEnum
      17: dup
      18: iconst_0
      19: getstatic     #17                 // Field CONST:LFooEnum;
      22: aastore
      23: putstatic     #19                 // Field ENUM$VALUES:[LFooEnum;
      26: return

  public static FooEnum[] values();
    // elided

  public static FooEnum valueOf(java.lang.String);
    // elided
}

CONST是一个最终的静态变量,其生命周期是类的生命周期。

如果类被垃圾收集,枚举将仅被垃圾收集。

来自Java语言规范,Java SE 8 Edition第8.9 枚举类型

枚举类型没有除其枚举常量定义的实例之外的实例。 尝试显式实例化枚举类型(第15.9.1节)是编译时错误。

除了编译时错误之外,还有三种机制可确保枚举类型的实例不会超出其枚举常量定义的实例:

Enum中的最终克隆方法确保永远不会克隆枚举常量。

禁止对枚举类型进行反射实例化。

序列化机制的特殊处理确保不会因反序列化而创建重复实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM