Add alias to an enum in java

6.8k Views Asked by At

I have a use case where I would like to access an enum instance with an alias of that enum.

The reason that I would like to access the enum instance with an alias is to allow accessing a value of an enum with non English characters (my specific use case is Hebrew).

The thing is that this is part of a framework and I need to be able to add multiple aliases to any given enum. It is needed to allow more natural language, as for the alias given would be used as part of a specification (gauge-java).

Any suggestions on how to do it properly?

EDIT: I'm adding an example:

Go to "בית"

this is a step that would be mapped to a method:

@Step("Go to <page>")
public void goToPage(Page page) {...}
2

There are 2 best solutions below

3
On

Since enum values are not good for specification by means of readability then you want to replace them with readable words. According to documentation you can pass enum as step parameter but in your case you can pass string as you want and then in the step method just to create enum from string using Factory class:

public class MyEnumUtil {

    private MyEnumUtil() {}

    public static MyEnum fromHebrew(String stringValue) {
        switch (stringValue) {
            case "צָפוֹן,": return MyEnum.NORTH;
            case "מזרח,": return MyEnum.EAST;
            case " מַעֲרָב,": return MyEnum.WEST;
            case "  דָרוֹם": return MyEnum.SOUTH;
            default: return null;
        }
    }
}

Then your step will be (of course in Hebrew)

@Step("Navigate towards <directionString>")
public void navigate(String directionString) {
    MyEnum direction = MyEnumUtil.fromHebrew(directionString);
    // use enum
}
5
On

Enums can contain static and instance fields and have constructors like any other class:

enum Foo {
    A("alias1", "alias2"),
    B("alias3");

    private static final Map<String, Foo> gAliases = new HashMap<>();

    private Foo(String... aliases) {
        for(final String alias : aliases) {
            gAliases.put(alias, this);
        }
    }

    public static Foo forAlias(String alias) {
        return gAliases.get(alias);
    }
}

You could also omit the constructor and populate the alias map in a static initializer. But I like how the constructor makes it easy to read and maintain which aliases correspond to which constants.