Java Enum访问私有实例变量

时间:2012-02-27 12:21:45

标签: 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;
    }
}

我们怎么能这样做(以及真的值的变化)?

SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);

这个枚举实例是否隐式静态最终?此外,由于valueprivate,为什么我可以在其他类之外访问它?

6 个答案:

答案 0 :(得分:20)

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

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;
        }
    }
}

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

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

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

如果您想让SomeEnum正确不变,请制作value字段final

答案 1 :(得分:5)

你做不到

SomeEnum.VALUE1 = "Value4";
System.out.println(SomeEnum.VALUE1);

但你可以做到

SomeEnum.VALUE1.value = "Value4";
System.out.println(SomeEnum.VALUE1);

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

  

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

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

答案 2 :(得分:2)

  

这个枚举实例是不是隐式静态和最终的?

不。在您的示例中,value等枚举实例的成员可以是可变的。

(对您的示例中的实例(SomeEnum.VALUE1等)的引用是最终的和静态的。

  

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

你做不到。 enum是具有可枚举实例数的“类”。就是这样。

在这种情况下,

VALUE1是“类”SomeEnum的一个实例,因此SomeEnum.VALUE1.value是一个普通字段,与其他字段一样。


当你这样做时

System.out.println(SomeEnum.VALUE1);

您调用访问SomeEnum.VALUE1.toString字段的value。您没有立即访问value字段。

// Not possible since field is private.
System.out.println(SomeEnum.VALUE1.value);

答案 3 :(得分:2)

  

这个枚举实例是否隐式静态最终

Enum实例具有这些特征。但没有人说,这些实例是{em> immutable ,如IntegerString。所以你可以修改这些值。

这并不意味着这是推荐的做法!事实并非如此。

修改

再解释一下:

“Enum隐式静态”表示:

enum Foo { FOO };

这里FOO是静态的,虽然普通 Java语法会提示,FOO是一个错误地命名为常量的实例变量。您也可以像静态变量一样访问它。

“Enum隐含最终”意味着:

enum Foo { FOO, BAR };
Foo.FOO = Foo.BAR;

是不允许的。存储在FOO中的参考无法更改。您也无法创建新的实例

“枚举隐式不可变”意味着:Foo.FOO会给你一个对象。标准对象。如果对象允许修改自己的内容 - 那就是。这不是禁止的。

答案 4 :(得分:1)

枚举本身(VALUE1VALUE2VALUE3)是静态的和最终的。它们是SomeEnum类型的三个实例,我们无法更改它们(例如从枚举中删除VALUE1或在运行时添加VALUE4)。

但我们可以向实例添加公共字段(如示例中所示)并在运行时更改这些字段的内容。

答案 5 :(得分:1)

SomeEnum.VALUE1 =" Value4" ......实际上不起作用。

更重要的是,VALUE1将始终仅等于VALUE1而不是VALUE2或VALUE3,与其成员值无关。