繁体   English   中英

为什么在枚举设置为null后保留此值

[英]Why is does this value get retained after enum is set to null

尝试创建标志枚举时,使其包含多个状态。 我注意到了一些奇怪的事情。 更改枚举的内部值时,其名称不变。 奇怪的是,在我将值明确设置为0之前,此内部值(在我的情况下为int)保持最高值。

这是我用来进一步测试的枚举

public enum flags {
   None(0), flag1(1 << 0);

   private int value;

   private flags(int value) {
       this.value = value;
   }

   public boolean hasFlag(flags flag) {
       return (flag.value & value) == flag.value;
   }

   public void addFlag(flags flag) {
       value |= flag.value;
   }

   public int getValue() {
       return value;
   }

   public void setValue(int value) {
      this.value = value;
   }
}

我已经尝试过这些事情来将枚举值设置为0

    flags flag = flags.None;
    System.out.println(flag + " " + flag.getValue());
    // prints: None 0

    flag.addFlag(flags.flag1);
    System.out.println(flag + " " + flag.getValue());
    // prints: None 1

    flag = flags.None;
    System.out.println(flag + " " + flag.getValue());
    // prints: None 1 even though
    // its been set to flags.None which has a value of 0

    flag = null;
    flag = flags.None;
    System.out.println(flag + " " + flag.getValue());
    // prints: None 1. Even though the enum has been set to null before
    // setting the value to null

    flag = null;
    flag = flags.flag1;
    flag = flags.None;
    System.out.println(flag + " " + flag.getValue());
    // prints: None 1. Even though it is set to
    // another value after being set to null
    // and then set to None

    flag.setValue(0);
    System.out.println(flag + " " + flag.getValue());
    // prints: None 0. As expected

我的问题如下:为什么值如此持久,这里发生了什么?

我认为您严重误解了Java枚举的目的和功能。 根据定义,枚举是singletons ,这意味着枚举的每个定义在每次运行时都只能构造一次。 换句话说,您不能有两个flags.None flags.None是一个单一的事情你永远的应用程序运行时。

但是,您可以 -声明引用枚举的多个字段。 就像您可能说int i = 0 ,您可以声明一个“ flags”变量,例如flags myFlag = flags.None 这不会创建“ None”的新版本,而是对“ None”枚举的引用。 修改状态“ None”(恕我直言,这是个坏主意)将在整个应用程序中全局显示。

另外,您不应该将自己的琐事拖入编写的枚举中。 可能我建议您看看EnumSet吗? 这将产生更具可读性的代码,并且是实现您想要完成的目标的理想方式。

问题是,枚举的每个值只有一个实例(在您的情况下为Noneflag1 )。 因此,编辑该实例将永远更改它。 如果将标志添加到None ,则原始的None实例将更改(与flags.None的相同),并且将一直保持这种状态,直到再次更改它为止。

声明枚举时,实际上是在声明一系列静态对象。 通过更改静态对象的成员(addFlag调用),您已经对其进行了修改,因此所有其他引用都将引用该相同的值。

您误解的另一部分是,当您将标志分配给null或另一个值时,您并没有清除枚举。 Java是按引用传递的,因此您要做的就是更改flag变量所引用的内容。 这就是为什么在代码末尾,当您将Value设置为0时,枚举的None成员再次按预期显示0。 您可以通过重新分配None和flag1枚举成员的值来解决这个问题。

最后,这实际上不是要使用枚举的方式。 我不确定您要为此使用什么,但是您可以根据此处提供的内容轻松使用常规类。 当您要进行严格的类型检查并明确指示(命名)每个值的含义时,最好使用枚举。 例如错误代码枚举。 但是其中的值不应重新分配或修改。 当然,您显然可以做到这一点,我只是说这可能会使看到您工作的其他人感到困惑。

暂无
暂无

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

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