Post

Java) enum

Java) enum

This post was migrated from Tistory. You can find the original here.

enum

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Test {
    enum Direction {
        EAST("East", 10),
        WEST("West", -10),
        SOUTH("South", -20),
        NORTH("North", 20);

        private final String label;
        private final int val;

        Direction(String label, int val) {
            this.label = label;
            this.val = val;
        }

        public String label() {
            return label;
        }

        public int val() {
            return val;
        }

        private static final Map<String, Direction> BY_LABEL =
                Stream.of(values()).collect(Collectors.toMap(Direction::label, Function.identity()));

        private static final Map<Integer, Direction> BY_NUMBER =
                Stream.of(values()).collect(Collectors.toMap(Direction::val, Function.identity()));

        public static Direction valueOfLabel(String label) {
            return BY_LABEL.get(label);
        }

        public static Direction valueOfNumber(int val) {
            return BY_NUMBER.get(val);
        }
    }

    public static void main(String[] args) {
        System.out.println(Direction.valueOfLabel("West").val());
    }
}

An enum’s constructor is private, so it can’t be called directly — it’s invoked automatically.

values() is a method the compiler automatically adds to every enum type.
static E[] values()

Among the members defined in java.lang.Enum, the common superclass of all enums, there’s ordinal().
It returns the position (starting at 0) in which the enum constant was declared, as an integer.

While ordinal() returns the declaration order, that value is meant purely for internal use and generally shouldn’t be treated as the “value” of the enum constant. That’s why we instead add an instance field and constructor, and expose it through a getter method.

One more thing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public enum Test {
    USER(Authority.USER),
    ADMIN(Authority.ADMIN);

    private final String authority;

    Test(String authority) {
        this.authority = authority;
    }

    public String getAuthority() {
        return this.authority;
    }

    public static class Authority {
        public static final String USERCODE = "ROLE_12%755642%1021654%8789";
        public static final String ADMIN = "ROLE_ADMIN";
    }
}

As shown above, you can define a static class to hold constants. What’s the benefit of that?

If the USER constant were declared as USER("ROLE_12%755642%1021654%8789"), it would be hard to tell what that constant actually means just by looking at it. Using Authority.USERCODE instead makes it clear that this constant represents a user code.

This post is licensed under CC BY-NC 4.0 by the author.