Java Enum访问私有实例变量

Buh*_*ndi 16 java enums

考虑这个例子:

enum SomeEnum {
    VALUE1("value1"),
    VALUE2("value2"),
    VALUE3("value3")
    ;
    private String value;

    private SomeEnum(final String value) {
        this.value = value;
    }

    //toString
    public String toString() {
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们怎么能这样做(价值真的发生了变化)?

SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);
Run Code Online (Sandbox Code Playgroud)

那个枚举实例是不是隐式静态最终的?此外,由于value就是private为什么我可以访问其他类之外?

Jon*_*eet 23

似乎没有人解决私人问题.我的猜测是你从一个包含类型访问私有字段 - 你的枚举实际上是一个嵌套类型,如下所示:

class Test
{
    static void Main() {
        // Entirely valid
        SomeEnum.VALUE1.value = "x";
    }

    enum SomeEnum {
        VALUE1("value1");

        private String value;

        private SomeEnum(final String value) {
            this.value = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这完全合法且正常 - 您始终可以从包含类型访问嵌套类型的私有成员.

如果您将枚举设为顶级类型,则不会看到此内容.

至于改变价值观 - 正如其他人所说的那样,VALUE1是隐含的静态和最终的,但这并不能阻止你改变VALUE1.value.同样,这完全符合Java在其他地方的工作方式 - 如果你有一个类型的静态字段List,你仍然可以向它添加条目,因为那不是修改字段本身.

如果你想做出SomeEnum正确的不可变,请创建该value字段final.

  • 这只是一个观点:“枚举类型是一种其字段由一组固定的常量组成的类型”。我可以在枚举中拥有可变属性,并可以随时随意更改它。 (2认同)
  • @TheEliteGentleman:是的,您可以-这是一个非常糟糕的主意。枚举类型是具有固定类型的* instances *的类型。因此,在`SomeEnum`类型中有一组静态final字段,它们是* SomeEnum`类型的字段。这些用于访问实例。您声明的任何额外字段都与其他字段完全一样工作-您可以具有静态字段或实例字段,最终字段或非最终字段等。 (2认同)
  • @TheEliteGentleman:所以你的枚举不仅仅是可变的,而是*正在变异*?如果是这样,那听起来像是真正需要尽快解决的代码. (2认同)

Pet*_*rey 5

你做不到

SomeEnum.VALUE1 = "Value4";
System.out.println(SomeEnum.VALUE1);
Run Code Online (Sandbox Code Playgroud)

但你可以做到

SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);
Run Code Online (Sandbox Code Playgroud)

并且value确实发生了变化,但不是静态的最终 VALUE1.

此外,由于值是私有的,为什么我可以在其他类之外访问它?

您可以访问外部/内部类中的私有字段,但是我找不到可以从另一个类(例如,在同一个包中)访问它的示例.