关于Java:什么是枚举,为什么它们有用?

What are enums and why are they useful?

今天我浏览了一下这个网站上的一些问题,我发现有一个提到在singleton模式中使用了一个enum,它声称线程安全对这种解决方案有好处。

我从来没有使用EDCOX1,0的S,我已经在Java编程超过一年多了。很明显他们改变了很多。现在他们甚至在自己内部充分支持OOP。

现在,我为什么要在日常编程中使用枚举,为什么要使用枚举?


当变量(尤其是方法参数)只能从一小组可能的值中取出一个值时,应该始终使用枚举。例如类型常量(合同状态:"永久"、"临时"、"学徒")或标志("立即执行"、"延迟执行")。

如果使用枚举而不是整数(或字符串代码),则会增加编译时检查,并避免错误传入无效常量,并记录哪些值是合法的。

顺便说一句,枚举的过度使用可能意味着你的方法做的太多(通常最好有几个单独的方法,而不是一个采用多个标志来修改它所做的工作的方法),但是如果你必须使用标志或类型代码,那么枚举就是一种方法。

举个例子,哪个更好?

1
2
3
4
5
6
/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */

public int countFoobangs(int type)

对战

1
2
3
4
5
6
7
8
9
10
11
12
/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET,
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */

public int countFoobangs(FB_TYPE type)

方法调用,如:

1
int sweetFoobangCount = countFoobangs(3);

然后变成:

1
int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

在第二个示例中,可以立即清楚地看到哪些类型是允许的,文档和实现不能不同步,编译器可以强制执行这一点。另外,一个无效的调用

1
int sweetFoobangCount = countFoobangs(99);

已经不可能了。


为什么要使用任何编程语言功能?我们有语言的原因是

  • 程序员以计算机可以使用的形式高效、正确地表达算法。
  • 维护人员理解其他人编写的算法并正确地进行更改。
  • Enums在不编写大量样板文件的情况下提高了正确性和可读性的可能性。如果您愿意编写样板文件,那么可以"模拟"枚举:

    1
    2
    3
    4
    5
    6
    public class Color {
        private Color() {} // Prevent others from making colors.
        public static final Color RED = new Color();
        public static final Color AMBER = new Color();
        public static final Color GREEN = new Color();
    }

    现在你可以写:

    1
    Color trafficLightColor = Color.RED;

    上面的样板与

    1
    public enum Color { RED, AMBER, GREEN };

    两者都提供来自编译器的相同级别的检查帮助。样板文件只是更多的打字。但是节省大量的输入会使程序员更高效(见1),所以这是一个值得一试的特性。

    至少还有一个原因是值得的:

    switch语句

    上面的static final枚举模拟没有给您提供一个很好的switch案例。对于EnUM类型,Java交换机使用其变量的类型来推断EnUM实例的范围,因此对于EDCOX1,2以上,您只需要说:

    1
    2
    3
    4
    5
    6
    Color color = ... ;
    switch (color) {
        case RED:
            ...
            break;
    }

    注意,在这种情况下不是Color.RED。如果不使用枚举,则在switch中使用命名数量的唯一方法是:

    1
    2
    3
    4
    5
    public Class Color {
        public static final int RED = 0;
        public static final int AMBER = 1;
        public static final int GREEN = 2;
    }

    但现在保存颜色的变量必须是int类型。枚举和static final模拟的良好编译器检查已不复存在。不高兴。

    折衷办法是在模拟中使用标量值成员:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Color {
        public static final int RED_TAG = 1;
        public static final int AMBER_TAG = 2;
        public static final int GREEN_TAG = 3;

        public final int tag;

        private Color(int tag) { this.tag = tag; }
        public static final Color RED = new Color(RED_TAG);
        public static final Color AMBER = new Color(AMBER_TAG);
        public static final Color GREEN = new Color(GREEN_TAG);
    }

    现在:

    1
    2
    3
    4
    5
    6
    Color color = ... ;
    switch (color.tag) {
        case Color.RED_TAG:
            ...
            break;
    }

    但请注意,还有更多的样板文件!

    将枚举用作单例

    从上面的样板文件中,您可以看到为什么枚举提供了实现单例的方法。不是写:

    1
    2
    3
    4
    5
    6
    public class SingletonClass {
        public static final void INSTANCE = new SingletonClass();
        private SingletonClass() {}

        // all the methods and instance data for the class here
    }

    然后用

    1
    SingletonClass.INSTANCE

    我们可以说

    1
    2
    3
    4
    5
    public enum SingletonClass {
        INSTANCE;

        // all the methods and instance data for the class here
    }

    这给了我们同样的东西。我们可以摆脱这个问题,因为Java枚举被实现为完整的类,只有少量的语法糖撒在上面。这又是一个不那么简单的样板,但是除非您熟悉这个习语,否则它是不明显的。我也不喜欢这样一个事实,即你得到了各种枚举函数,尽管它们对单例来说没有多大意义:ordvalues等(实际上有一个更复杂的模拟,其中Color extends Integer可以与开关一起使用,但它非常复杂,它更清楚地表明了为什么enum是一个更好的想法。)

    线程安全性

    线程安全是一个潜在的问题,只有在不加锁的情况下缓慢地创建单例时。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class SingletonClass {
        private static SingletonClass INSTANCE;
        private SingletonClass() {}
        public SingletonClass getInstance() {
            if (INSTANCE == null) INSTANCE = new SingletonClass();
            return INSTANCE;
        }

        // all the methods and instance data for the class here
    }

    如果许多线程同时调用getInstance,而INSTANCE仍然为空,则可以创建任意数量的实例。这很糟糕。唯一的解决方案是添加synchronized访问以保护变量INSTANCE

    但是,上面的static final代码没有这个问题。它在类加载时急切地创建实例。类加载已同步。

    enum单例非常懒惰,因为它直到第一次使用才初始化。Java初始化也是同步的,因此多个线程不能初始化EDOCX1的12个以上实例。您得到的是一个延迟初始化的单例,代码很少。唯一的缺点是语法比较模糊。您需要了解这个习语,或者彻底了解类装载和初始化是如何工作的,以了解发生了什么。


    除了前面提到的用例之外,我经常发现枚举对于实现策略模式很有用,遵循一些基本的OOP准则:

  • 拥有数据所在的代码(也就是说,在枚举本身中——或者通常在枚举常量中,这些常量可以重写方法)。
  • 实现一个接口(或多个接口),以便不将客户端代码绑定到枚举(枚举只提供一组默认实现)。
  • 最简单的例子是一组Comparator实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    enum StringComparator implements Comparator<String> {
        NATURAL {
            @Override
            public int compare(String s1, String s2) {
                return s1.compareTo(s2);
            }
        },
        REVERSE {
            @Override
            public int compare(String s1, String s2) {
                return NATURAL.compare(s2, s1);
            }
        },
        LENGTH {
            @Override
            public int compare(String s1, String s2) {
                return new Integer(s1.length()).compareTo(s2.length());
            }
        };
    }

    这个"模式"可以在更复杂的场景中使用,广泛地使用枚举附带的所有优点:遍历实例,依赖于实例的隐式顺序,通过实例的名称检索实例,为特定上下文提供正确实例的静态方法等,并且仍然将这些隐藏在接口后面。因此,如果您希望在"默认选项"中有一些不可用的东西,您的代码可以在不进行修改的情况下与自定义实现一起工作。

    我已经看到这成功地应用于建模时间粒度的概念(每日、每周等),其中所有的逻辑都封装在一个枚举中(为给定的时间范围选择正确的粒度,作为常量方法绑定到每个粒度的特定行为等)。不过,服务层所看到的Granularity只是一个接口。


    其他答案中没有一个能使Enums特别强大的是拥有模板方法的能力。方法可以是基枚举的一部分,并由每个类型重写。而且,通过将该行为附加到枚举中,它通常消除了对else是否构造或switch语句的需要,正如这个博客文章所演示的那样——enum.method()在条件内部执行最初执行的操作。同样的例子也显示了静态导入与枚举的使用,以及生成更清晰的DSL类代码。

    其他一些有趣的特性包括Enums为equals()toString()hashCode()提供实现,以及实现SerializableComparable

    对于所有的枚举必须提供完整的运行,我强烈推荐Bruce Eckel的想法在Java第四版,它致力于整个章节的主题。特别有启发性的例子包括石头、纸、剪刀(即Roshambo)作为枚举的游戏。


    从Java文档——

    You should use enum types any time you
    need to represent a fixed set of
    constants. That includes natural enum
    types such as the planets in our solar
    system and data sets where you know
    all possible values at compile
    time—for example, the choices on a
    menu, command line flags, and so on.

    一个常见的例子是用枚举类型替换一组私有静态final int常量(在合理的常量数量内)的类。基本上,如果您认为在编译时知道"something"的所有可能值,那么可以将其表示为枚举类型。枚举在带有常量的类上提供可读性和灵活性。

    我能想到的枚举类型的其他几个优点。它们始终是特定枚举类的一个实例(因此单例到达时使用枚举的概念)。另一个优点是可以将枚举用作switch case语句中的类型。还可以在枚举上使用ToString()将其打印为可读字符串。


    Now why and what for should I used
    enum in day to day programming?

    在提高可读性的同时,可以使用枚举表示较小的固定常量集或内部类模式。此外,当在方法参数中使用时,枚举可以加强一定的刚度。它们提供了将信息传递给构造器的有趣可能性,比如Oracle网站上的行星示例,正如您所发现的,还允许创建单例模式的简单方法。

    例如:当添加.分隔符而不是所有整数时,Locale.setDefault(Locale.US)的读取比Locale.setDefault(1)更好,并且强制使用IDE中显示的固定值集。


    enums以自记录的方式枚举一组固定的值。
    它们使您的代码更显式,也更不容易出错。

    为什么不用Stringint代替enum作为常量呢?

  • 编译器不允许输入错误,也不允许值超出固定值设置,因为枚举本身就是类型。后果:
    • 你不必写一个前提条件(或者一个手动的if)来保证你的论点在有效范围内。
    • 类型不变量是免费的。
  • 枚举可以有行为,就像任何其他类一样。
  • 无论如何,使用Strings可能需要类似数量的内存(这取决于enum的复杂性)。
  • 此外,每个enum的实例都是一个类,您可以为其定义自己的行为。

    另外,它们在创建实例(加载枚举时)时确保线程安全,这在简化单例模式方面有着巨大的应用。

    这个博客演示了它的一些应用程序,例如解析器的状态机。


    有必要知道,enums与其他具有Constant字段和private constructor字段的类一样。

    例如,

    1
    2
    3
    4
    public enum Weekday
    {
      MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    }

    编译器编译如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Weekday extends Enum
    {
      public static final Weekday MONDAY  = new Weekday("MONDAY",   0 );
      public static final Weekday TUESDAY = new Weekday("TUESDAY", 1 );
      public static final Weekday WEDNESDAY= new Weekday("WEDNESDAY", 2 );
      public static final Weekday THURSDAY= new Weekday("THURSDAY", 3 );
      public static final Weekday FRIDAY= new Weekday("FRIDAY", 4 );
      public static final Weekday SATURDAY= new Weekday("SATURDAY", 5 );
      public static final Weekday SUNDAY= new Weekday("SUNDAY", 6 );

      private Weekday( String s, int i )
      {
        super( s, i );
      }

      // other methods...
    }

    enum表示枚举,即逐项提及(许多事情)。

    An enum is a data type that contains fixed set of constants.

    An enum is just like a class, with a fixed set of instances known at compile time.

    例如:

    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
    public class EnumExample {
        interface SeasonInt {
            String seasonDuration();
        }

        private enum Season implements SeasonInt {
            // except the enum constants remaining code looks same as class
            // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
            WINTER(88,"DEC - FEB"), SPRING(92,"MAR - JUN"), SUMMER(91,"JUN - AUG"), FALL(90,"SEP - NOV");

            private int days;
            private String months;

            Season(int days, String months) { // note: constructor is by default private
                this.days = days;
                this.months = months;
            }

            @Override
            public String seasonDuration() {
                return this+" ->"+this.days +"days,  " + this.months+" months";
            }

        }
        public static void main(String[] args) {
            System.out.println(Season.SPRING.seasonDuration());
            for (Season season : Season.values()){
                System.out.println(season.seasonDuration());
            }

        }
    }

    枚举的优点:

    • 枚举提高了编译时检查的类型安全性,以避免在运行时出错。
    • 枚举可以很容易地在开关中使用
    • 枚举可以遍历
    • 枚举可以有字段、构造函数和方法
    • 枚举可以实现许多接口,但不能扩展任何类,因为它在内部扩展枚举类

    为了更多


    什么是枚举

    • 枚举是为枚举新数据类型定义的关键字。类型安全枚举应充分使用。特别是,它们是简单字符串或int常量的强大替代品,在更老的API中用于表示相关项集。

    为什么使用枚举

    • 枚举是java.lang.enum的隐式最终子类
    • 如果枚举是类的成员,则它是隐式静态的
    • new不能与枚举一起使用,即使在枚举类型本身中也是如此。
    • name和valueof仅使用枚举常量的文本,而toString可能被重写以提供任何内容(如果需要)
    • 对于枚举常量,equals和==等于相同的值,并且可以互换使用。
    • 枚举常量是隐式公共静态final

    注释

    • 枚举不能扩展任何类。
    • 枚举不能是超类。
    • 枚举常量的出现顺序称为其"自然顺序",并定义其他项使用的顺序:compareto、值的迭代顺序、enumset、enumset.range。
    • 枚举可以有构造函数、静态块和实例块、变量和方法,但不能有抽象方法。


    除了别人说的……在我以前工作过的一个旧项目中,实体(独立应用程序)之间的许多通信都使用了表示一个小集合的整数。用静态方法将集合声明为enum,可以从value和viceversa中获取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
    enum ProtocolType {
        TCP_IP (1,"Transmission Control Protocol"),
        IP (2,"Internet Protocol"),
        UDP (3,"User Datagram Protocol");

        public int code;
        public String name;

        private ProtocolType(int code, String name) {
            this.code = code;
            this.name = name;
        }

        public static ProtocolType fromInt(int code) {
        switch(code) {
        case 1:
            return TCP_IP;
        case 2:
            return IP;
        case 3:
            return UDP;
        }

        // we had some exception handling for this
        // as the contract for these was between 2 independent applications
        // liable to change between versions (mostly adding new stuff)
        // but keeping it simple here.
        return null;
        }
    }

    使用ProtocolType.fromInt(2)从接收值(如1、2)创建enum对象使用myEnumObj.name写入日志

    希望这有帮助。


    枚举继承Object类和抽象类enum的所有方法。因此,可以使用它的方法进行反射、多线程、序列化、比较等。如果只是声明一个静态常量而不是枚举,则不能。此外,枚举的值也可以传递给DAO层。

    下面是一个示例程序。

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    public enum State {

        Start("1"),
        Wait("1"),
        Notify("2"),
        NotifyAll("3"),
        Run("4"),
        SystemInatilize("5"),
        VendorInatilize("6"),
        test,
        FrameworkInatilize("7");

        public static State getState(String value) {
            return State.Wait;
        }

        private String value;
        State test;

        private State(String value) {
            this.value = value;
        }

        private State() {
        }

        public String getValue() {
            return value;
        }

        public void setCurrentState(State currentState) {
            test = currentState;
        }

        public boolean isNotify() {
            return this.equals(Notify);
        }
    }

    public class EnumTest {

        State test;

        public void setCurrentState(State currentState) {
            test = currentState;
        }

        public State getCurrentState() {
            return test;
        }

        public static void main(String[] args) {
            System.out.println(State.test);
            System.out.println(State.FrameworkInatilize);
            EnumTest test=new EnumTest();
            test.setCurrentState(State.Notify);
            test. stateSwitch();
        }

        public void stateSwitch() {
            switch (getCurrentState()) {
            case Notify:
                System.out.println("Notify");
                System.out.println(test.isNotify());
                break;
            default:
                break;
            }
        }
    }

    Enum代表"枚举类型"。它是一种数据类型,有一组固定的常量,您自己定义。


    枚举?为什么要使用它?我觉得你什么时候用它更容易理解。我也有同样的经历。

    假设您有一个创建、删除、编辑和读取数据库操作。

    现在,如果创建枚举作为操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public enum operation {
        create("1")
        delete("2")
        edit("3")
        read("4")

        // You may have is methods here
        public boolean isCreate() {
            return this.equals(create);
        }
        // More methods like the above can be written

    }

    现在,您可以声明如下内容:

    1
    2
    3
    4
    private operation currentOperation;

    // And assign the value for it
    currentOperation = operation.create

    所以你可以在很多方面使用它。对于特定的事物拥有枚举总是很好的,因为上面例子中的数据库操作可以通过检查当前操作来控制。也许可以说,这也可以用变量和整数值来实现。但我相信枚举是一种更安全的编程方法。

    另一件事:我想每个程序员都喜欢布尔型,不是吗?因为它只能存储两个值,两个特定的值。因此,可以认为枚举具有相同类型的工具,用户将在其中定义它将以稍微不同的方式存储的值的数量和类型。:)


    在我看来,你到现在为止得到的所有答案都是有效的,但根据我的经验,我会用几句话来表达:

    如果希望编译器检查标识符值的有效性,请使用枚举。

    否则,您可以像往常一样使用字符串(可能为应用程序定义了一些"约定"),并且您将非常灵活…但是,对于字符串中的拼写错误,您将无法获得100%的安全性,并且只能在运行时实现这些安全性。


    使用Enums进行类型安全,这是一种语言功能,因此您通常会得到:

    • 编译器支持(立即查看类型问题)
    • IDES中的工具支持(在交换情况下自动完成…)

    枚举可以有方法、构造函数,甚至可以在枚举内使用枚举,并将枚举与接口结合起来。

    将枚举视为类型来替换一组定义良好的int常量(从C/C++中继承的Java)。

    这本书的有效Java第二版有一个完整的章节对他们,并进入更多的细节。另请参阅此堆栈溢出日志。


    Java允许您将变量限制为只有几个预定义值中的一个——换句话说,枚举列表中的一个值。使用enums有助于减少代码中的错误。下面是一个类外的enums的例子:

    1
    2
    enums coffeesize{BIG , HUGE , OVERWHELMING };
    //This semicolon is optional.

    这就限制了coffeesizeBIGHUGEOVERWHELMING作为变量。


    这里有很多答案,只想指出两个具体的答案:

    1)在Switch-case语句中用作常量。switch case不允许将字符串对象用于case。Enum很有用。更多:http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

    2)再次实施Singleton Design Pattern枚举,来救援。用法:这里:在Java中使用EnUM作为单体的最佳方法是什么?


    让我大吃一惊的是:这个枚举有一个私有的构造函数,只能通过公共枚举访问:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    enum RGB {
        RED("Red"), GREEN("Green"), BLUE("Blue");

        public static final String PREFIX ="color";

        public String getRGBString() {
            return PREFIX + color;
        }

        String color;

        RGB(String color) {
            this.color = color;
        }
    }

    public class HelloWorld {
        public static void main(String[] args) {
            String c = RGB.RED.getRGBString();
            System.out.print("Hello" + c);
        }
    }


    对于我来说,为了使代码在将来可读,最有用的可应用的枚举情况将在下面的代码片段中表示:

    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
    43
    44
    public enum Items {
        MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menuPrm) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menuPrm);
        View itemChooserLcl;
        for (int i = 0; i < menuPrm.size(); i++) {
            MenuItem itemLcl  = menuPrm.getItem(i);
                itemChooserLcl = itemLcl.getActionView();
                if (itemChooserLcl != null) {
                     //here Im marking each View' tag by enume values:
                    itemChooserLcl.setTag(Items.values()[i]);
                    itemChooserLcl.setOnClickListener(drawerMenuListener);
                }
            }
        return true;
    }
    private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Items tagLcl= (Items) v.getTag();
            switch (tagLcl){
                case MESSAGES: ;
                break;
                case CHATS : ;
                break;
                case CITY_ONLINE : ;
                break;
                case FRIENDS : ;
                break;
                case  PROFILE: ;
                break;
                case  SETTINGS: ;
                break;
                case  PEOPLE_SEARCH: ;
                break;
                case  CREATE_CHAT: ;
                break;
            }
        }
    };

    到目前为止,我从未需要使用枚举。我从1.5版或Tiger(当时称之为版本Tiger)开始就一直在阅读关于它们的文章。他们从来没有真正解决过我的"问题"。对于那些使用它的人(我看到很多人使用它),一定要确定它确实有某种用途。我的2镑。


    而不是做一堆const int声明

    您可以将它们全部分组为一个枚举

    所以这一切都是由他们所属的共同团体组织的


    根据我的经验,我见过枚举的使用有时会导致系统很难更改。如果您对一组经常更改的特定于域的值使用枚举,并且它有许多依赖于它的其他类和组件,那么您可能需要考虑不使用枚举。

    例如,使用枚举进行市场/交易所的交易系统。那里有很多市场,几乎可以肯定会有很多子系统需要访问这个市场列表。每次你想要一个新的市场加入到你的系统中,或者如果你想要移除一个市场,那么在阳光下的一切都有可能需要重建和发布。

    一个更好的例子是类似产品类别的类型。假设您的软件管理百货公司的库存。产品类别很多,这一类别列表可能会改变的原因很多。管理者可能希望储备一个新的产品线,摆脱其他产品线,并可能不时地重新组织类别。如果你仅仅因为用户想要添加一个产品类别就必须重新构建和重新部署你的所有系统,那么你已经采取了一些简单和快速的方法(添加一个类别),并使之变得非常困难和缓慢。

    归根结底,如果您所表示的数据随着时间的推移是非常静态的,并且依赖关系的数量有限,那么枚举就很好了。但是,如果数据变化很大并且有很多依赖项,那么您需要一些在编译时没有检查的动态数据(比如数据库表)。


    我将使用Enums作为一种有用的映射工具,避免使用多个if-else。前提是实现了一些方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public enum Mapping {

        ONE("1"),
        TWO("2");

        private String label;

        private Mapping(String label){
            this.label = label;
        }

        public static Mapping by(String label) {

            for(Mapping m: values() {
                if(m.label.equals(label)) return m;
            }

            return null;
        }

    }

    因此,方法by(String label)允许您通过非枚举获得枚举值。此外,可以发明两个枚举之间的映射。除了"一对一"默认关系之外,还可以尝试"1对多"或"多对多"

    最后,EDCOX1 2是一个Java类。因此,您可以在其中包含main方法,当需要立即对args执行一些映射操作时,这可能很有用。