SomeEnum [] vals = SomeEnum.values()变量定义后变化?

时间:2015-12-07 07:39:03

标签: java enums

PlayerDefaults[] pds;
if (pds == null)
{
    pds = PlayerDefaults.values();
}
PlayerDefaults.Name.value = "Lightspeed360";

在Name设置为" Lightspeed360"之前设置完美。定义后更改为它? 我很困惑请解释/帮助。
ALL CODE here
以下是运行您在上面看到的代码时得到的日志:

TEST BEFORE> $Name$
TEST BEFORE> 2000
TEST BEFORE> 0
TEST AFTER> Lightspeed360
TEST AFTER> 2000
TEST AFTER> 0

2 个答案:

答案 0 :(得分:1)

示例PlayerDefaults.Name中PlayerDefaults中的每个枚举都类似于

public static final PlayerDefaults Name = new PlayerDefaults();

因此,无论何时访问PlayerDefaults.Name,您都将获得相同的对象。

有关如何使用枚举的更多详细信息,建议您阅读“Effective Java”第6章

编辑:

您可以直接在DataDefaults中访问PlayerDefaults.Name.value的原因是因为PlayerDefaults是DataDefaults的内部枚举。 您可以将每个PlayerDefaults视为DataDefaults的静态成员。 由于整个班级都在你的控制之下,因此你不应该让玩家默认的任何领域的价值发生变化。

答案 1 :(得分:1)

你的枚举值不会改变。

只是这些枚举值的某些成员变量(你碰巧命名为value)正在发生变化。从设计角度来看,这不是一件好事,但它是合法的。

您将无法将项目添加到枚举中 - 这将破坏枚举合同。

事实上,枚举可以和Java中的类很相似。有些人甚至喜欢他们为单身人士(虽然这不是最伟大的想法)。所以你可以拥有成员变量,方法和许多其他东西。但是你总是只有有限数量的项目 - 你在enum声明开头列举的项目。

将此更改检查到您的调试输出:

    for (PlayerDefaults pd : pds)
    {
        System.out.println("Name before> " + pd.name());
        System.out.println("TEST BEFORE> " + pd.value);
    }
    PlayerDefaults.Name.value = name;
    for (PlayerDefaults pd : pds)
    {
        System.out.println("Name after> " + pd.name());
        System.out.println("TEST AFTER> " + pd.value);
    }

您仍然可以获得相同的枚举对象 - 这些对象由name()唯一标识。

根据您的问题修改

怎么样:

public static enum PlayerDefaults
{

    Name("$Name$"),
    Money(2000),
    Warnings(0);

    public static void reset() {
        Name.value = "$Name";
        Money.value = 2000;
        Warnings.value = 0;
    }

现在如果你需要重置你的枚举,你可以这样做。 但是这会喊“我不是线程安全的”。如果在将其设置为一个值时,另一个线程中的其他人重置了......?

最好在代码中保留Map<PlayerDefaults,Object>,并限制PlayerDefaults仅代表默认值的名称,而不是值。

使用地图的示例

考虑这个例子,仅使用值初始化Map:

import java.util.HashMap;
import java.util.Map;

public class DataDefaults
{

    Map<PlayerDefaults, Object> playerData = new HashMap<PlayerDefaults,Object>();

    public DataDefaults(final String name)  {
        if (playerData.isEmpty())
        for (PlayerDefaults pd : PlayerDefaults.values()) {
            playerData.put(pd, pd.value);           
        }
        playerData.put(PlayerDefaults.Name, name);      
    }

    void close() {
        for(Map.Entry<PlayerDefaults, Object> entry : playerData.entrySet()) {
            System.out.println(entry.getKey().name() + ": " + entry.getValue());
        }
    }

    public static enum PlayerDefaults { 
        Name("$Name$"),
        Money(2000),
        Warnings(0);

        private Object value; 
        private PlayerDefaults(Object value) {
            this.value = value;
        }       

        Object getValue() {
            return value;
        }
    }

    public static void main(String[] args) {
        new DataDefaults("WTF");
    }
}