Lightspeed360
Lightspeed360

Reputation: 161

SomeEnum[] vals = SomeEnum.values() varible changing after defined?

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

It sets perfectly before Name is set to "Lightspeed360" then changes to it after defined? I'm so confused please explain/help.
ALL CODE here
Here is the Log I get from running the code you see above:

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

Upvotes: 1

Views: 83

Answers (2)

Jan
Jan

Reputation: 13858

Your enum' values are not changing.

It's just that some member-variables of those enum values (which you happened to name value) are changing. Which is not a good thing from a design perspective, but it's legal.

You will not be able to add items to the enum that way - that would break the enum contract.

In fact, enums can be a lot like classes in Java. Some even like them for Singletons (although that's not the greatest of ideas). So you can have member variables, methods and a lot of other stuff. But you'll always have only a limited number of items - the ones you enumerated at the beginning of the enum declaration.

Check this change to your debug-output:

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

You still get the same enum objects - which are uniquely identified by their name().

Edit regarding your question

How about:

public static enum PlayerDefaults
{

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

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

So now if you need to reset your enum, you can do so. BUT this cries "I'm not thread-safe". What if while you're setting it to one value, someone else in another thread resets...?

It might be better to keep a Map<PlayerDefaults,Object> in your code and limit the PlayerDefaults to represent the names of the defaults only and not the values as well.

Example using Map

Consider this example using the values only for intializing a 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");
    }
}

Upvotes: 1

Roger Dwan
Roger Dwan

Reputation: 770

Each enumeration in the PlayerDefaults in your example PlayerDefaults.Name is like

public static final PlayerDefaults Name = new PlayerDefaults();

So whenever you access the PlayerDefaults.Name, you'll get the same object.

For more detail of how to use enum, I suggest you to read "Effective Java" chapter 6

EDIT:

The reason why you can access PlayerDefaults.Name.value directly inside the DataDefaults is because PlayerDefaults is an inner enum of DataDefaults. You can consider each PlayerDefaults as a static member of DataDefaults. Since the whole class is under your control, it is your responsibility that not let any value of field of a PlayerDefaults be changed.

Upvotes: 1

Related Questions