0

I have

No enum constant [...] at java.lang.Enum.valueOf(Enum.java:238)

when I try to decode a single char string to an enum.

What is wrong, how can I fix it?

public class testEnum {

    public enum Colors {
        RED("R"), GREEN("G"), BLUE("B");
        private final String code;

        Colors(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }

    }

    public static void main(String args[]) throws Exception {
        Colors c = Colors.valueOf("R");
        System.out.println(c);
    }
}

In this case, I expect RED to the ouput console.

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
E M
  • 17

4 Answers4

3

Colors.valueOf("R") is a implicitly declared method and a shortcut of Enum.valueOf(Colors.class, "R").

The documentation of Enum.valueOf states

@param name the name of the constant to return

Your constants are RED, GREEN, and BLUE.

You may wanna get an enum instance by its field.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
1

What is wrong, how can I fix it?

Java has no way of knowing that you're trying to pass a value of the code field to look up.

To fix it, either specify the entire name:

Colors.valueOf("RED")

or construct a Map<String, Colors> that you can look up instances from.

Map<String, Colors> map = new HashMap<>();
for (Colors colors : Colors.values()) {
  map.put(colors.code, colors);
}
// Assign to a field somewhere.

// Then, later:
Colors c = map.get("R");
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

From the docs of the method you have invoked:

valueOf:
Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)
Returns:
the enum constant with the specified name

In your case, enum 'name' will be "RED", "GREEN" or "BLUE". or if you want to refer to your enum it's Colors.RED.name()

If you want to lookup the Colors enum that corresponds to the code, what you can do is to have something like this:

public class Sampler {
    public enum Colors {
        RED("R"), BLUE("B"), GREEN("G");

        private static final Map<String, Colors> COLORS_MAP;

        static {
            COLORS_MAP = new HashMap<>();
            for(Colors color : values()) {
                COLORS_MAP.put(color.code, color);
            }
        }

        private final String code;

        Colors(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }

        public static Colors fromCode(String code) {
            return COLORS_MAP.get(code);
        }
    }

    public static void main(String[] args) {
        Colors c = Colors.fromCode("R");
        System.out.println(c);
    }
}
geneqew
  • 2,401
  • 5
  • 33
  • 48
0

My decision

public enum Colors {
    RED("R"), GREEN("G"), BLUE("B");
    private final String code;

    Colors(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static Colors ofCode(String code){
        Colors[] values = Colors.values();
        for (Colors value : values) {
            if(value.code.equals(code)){
                return value;
            }

        }
        throw new IllegalArgumentException("Code not found"); 
    }

}
Nikita
  • 94
  • 1
  • 3