Enumerations are a new data type in JDK 1.5. Enumerations can be used to describe specific business scenarios, such as spring, summer, fall, and winter of the year, as well as the days of the week from Monday to Sunday, various colors, and state information such as error codes.

Enumerations exist not only in the Java language, but also in other languages, such as C# and Python. However, I have found that enumerations are rarely used in real projects, so this article will give you a general idea of enumerations. At least one type of enumeration can be thought of when programming.

The structure of this article is as follows:

Seven ways to use enumeration

One of the main reasons many people don’t use enumerations is because they aren’t familiar with them, so let’s start with seven ways to use them.

Usage 1: Constant

Before JDK 1.5, we defined constants as public static final… But with enumeration, we can define these constants as an enumeration class, as follows:

public enum ColorEnum {  
  RED, GREEN, BLANK, YELLOW  
} 
Copy the code

2

Using enumerations in switch judgments makes the code more readable as follows:

enum ColorEnum {
    GREEN, YELLOW, RED
}
public class ColorTest {
    ColorEnum color = ColorEnum.RED;

    public void change(a) {
        switch (color) {
            case RED:
                color = ColorEnum.GREEN;
                break;
            case YELLOW:
                color = ColorEnum.RED;
                break;
            case GREEN:
                color = ColorEnum.YELLOW;
                break; }}}Copy the code

Usage three: Add methods to enumeration

We can add some methods to enumerations to give them more features, as follows:

public class EnumTest {
    public static void main(String[] args) {
        ErrorCodeEnum errorCode = ErrorCodeEnum.SUCCESS;
        System.out.println("Status code: + errorCode.code() + 
                           "Status information:"+ errorCode.msg()); }}enum ErrorCodeEnum {
    SUCCESS(1000."success"),
    PARAM_ERROR(1001."parameter error"),
    SYS_ERROR(1003."system error"),
    NAMESPACE_NOT_FOUND(2001."namespace not found"),
    NODE_NOT_EXIST(3002."node not exist"),
    NODE_ALREADY_EXIST(3003."node already exist"),
    UNKNOWN_ERROR(9999."unknown error");

    private int code;
    private String msg;

    ErrorCodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int code(a) {
        return code;
    }

    public String msg(a) {
        return msg;
    }

    public static ErrorCodeEnum getErrorCode(int code) {
        for (ErrorCodeEnum it : ErrorCodeEnum.values()) {
            if (it.code() == code) {
                returnit; }}returnUNKNOWN_ERROR; }}Copy the code

The execution results of the above programs are as follows:

Status code: 1000 Status information: SUCCESS

Usage four: Override enumeration methods

We can override some methods in enumerations to implement our own business. For example, we can override the toString() method as follows:

public class EnumTest {
    public static void main(String[] args) { ColorEnum colorEnum = ColorEnum.RED; System.out.println(colorEnum.toString()); }}enum ColorEnum {
    RED("Red".1), GREEN("Green".2), BLANK("White".3), YELLOW("Yellow".4);
    // Member variables
    private String name;
    private int index;

    // constructor
    private ColorEnum(String name, int index) {
        this.name = name;
        this.index = index;
    }

    // Override method
    @Override
    public String toString(a) {
        return this.index + ":" + this.name; }}Copy the code

The execution results of the above programs are as follows:

1: red

Usage 5: Implement the interface

Enumerations can be used to implement interfaces, but they cannot be used for inherited classes, because enumerations inherit from java.lang.Enum by default. In the Java language, multiple interfaces are allowed, but not multiple parent classes.

public class EnumTest {
    public static void main(String[] args) {
        ColorEnum colorEnum = ColorEnum.RED;
        colorEnum.print();
        System.out.println("Color:"+ colorEnum.getInfo()); }}interface Behaviour {
    void print(a);

    String getInfo(a);
}

enum ColorEnum implements Behaviour {
    RED("Red".1), GREEN("Green".2), BLANK("White".3), YELLOW("Yellow".4);
    private String name;
    private int index;

    private ColorEnum(String name, int index) {
        this.name = name;
        this.index = index;
    }

    @Override
    public void print(a) {
        System.out.println(this.index + ":" + this.name);
    }

    @Override
    public String getInfo(a) {
        return this.name; }}Copy the code

The execution results of the above programs are as follows:

1: red

Color: red

Usage six: Organize enumeration classes in an interface

We can create multiple enumerations in an interface, which is a good way to achieve “polymorphism”. That is, we can group enumerations that have the same properties but have slightly different implementations into one interface, as follows:

public class EnumTest {
    public static void main(String[] args) {
        // Assign the first enumeration class
        ColorInterface colorEnum = ColorInterface.ColorEnum.RED;
        System.out.println(colorEnum);
        // Assign the second enumeration classcolorEnum = ColorInterface.NewColorEnum.NEW_RED; System.out.println(colorEnum); }}interface ColorInterface {
    enum ColorEnum implements ColorInterface {
        GREEN, YELLOW, RED
    }
    enum NewColorEnum implements ColorInterface {
        NEW_GREEN, NEW_YELLOW, NEW_RED
    }
}
Copy the code

The execution results of the above programs are as follows:

RED

NEW_RED

Usage 7: Use enumerated collections

Related to enumeration classes in the Java language, there are two enumerated collection classes java.util.enumset and java.util.enummap, which can be used for more purposes.

An example of using EnumSet to ensure that elements are not duplicated and to obtain elements in a specified range is as follows:

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

public class EnumTest {
    public static void main(String[] args) {
        List<ColorEnum> list = new ArrayList<ColorEnum>();
        list.add(ColorEnum.RED);
        list.add(ColorEnum.RED);  // Repeat the element
        list.add(ColorEnum.YELLOW);
        list.add(ColorEnum.GREEN);
        // Remove duplicate data
        EnumSet<ColorEnum> enumSet = EnumSet.copyOf(list);
        System.out.println("Deweight:" + enumSet);

        // Get enumerations in the specified range (get all failed states)
        EnumSet<ErrorCodeEnum> errorCodeEnums = EnumSet.range(ErrorCodeEnum.ERROR, ErrorCodeEnum.UNKNOWN_ERROR);
        System.out.println("All failed states:"+ errorCodeEnums); }}enum ColorEnum {
    RED("Red".1), GREEN("Green".2), BLANK("White".3), YELLOW("Yellow".4);
    private String name;
    private int index;

    private ColorEnum(String name, int index) {
        this.name = name;
        this.index = index; }}enum ErrorCodeEnum {
    SUCCESS(1000."success"),
    ERROR(2001."parameter error"),
    SYS_ERROR(2002."system error"),
    NAMESPACE_NOT_FOUND(2003."namespace not found"),
    NODE_NOT_EXIST(3002."node not exist"),
    NODE_ALREADY_EXIST(3003."node already exist"),
    UNKNOWN_ERROR(9999."unknown error");

    private int code;
    private String msg;

    ErrorCodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int code(a) {
        return code;
    }

    public String msg(a) {
        returnmsg; }}Copy the code

The execution results of the above programs are as follows:

Deweight: [RED, GREEN, YELLOW]

All failed states: [ERROR, SYS_ERROR, NAMESPACE_NOT_FOUND, NODE_NOT_EXIST, NODE_ALREADY_EXIST, UNKNOWN_ERROR]

EnumMap is similar to HashMap, except that it is a collection of maps designed specifically for enumerations. It performs better than HashMap because it uses arrays as data storage structures instead of linked lists and red-black trees.

The following is an example for using EnumMap:

import java.util.EnumMap;

public class EnumTest {
    public static void main(String[] args) {
        EnumMap<ColorEnum, String> enumMap = new EnumMap<>(ColorEnum.class);
        enumMap.put(ColorEnum.RED, "Red");
        enumMap.put(ColorEnum.GREEN, "Green");
        enumMap.put(ColorEnum.BLANK, "White");
        enumMap.put(ColorEnum.YELLOW, "Yellow");
        System.out.println(ColorEnum.RED + ":"+ enumMap.get(ColorEnum.RED)); }}enum ColorEnum {
    RED, GREEN, BLANK, YELLOW;
}
Copy the code

The execution results of the above programs are as follows:

RED: the RED

Precautions for Use

Ali “Java development manual” on the relevant provisions of enumeration as follows, we need to pay a little attention to when using.

[Mandatory] All enumerated type fields must have comments stating the purpose of each data item.

Enumeration class names are suffixed with enums. Enumerator names must be all uppercase and separated by underscores (_). Note: Enumerations are simply special constant classes, and the constructor is forced to be private by default. Example: Enumerate the member name of ProcessStatusEnum: SUCCESS/UNKNOWN_REASON.

Suppose you don’t use enumerations

Before enumerations, in JDK 1.5, we used to use int constants to represent enumerations as follows:

public static final int COLOR_RED = 1;
public static final int COLOR_BLUE = 2;
public static final int COLOR_GREEN = 3;
Copy the code

But there are two possible problems with using ints:

First, ints are inherently unsafe. If a programmer defines an int without a final keyword, there is a risk that it will be modified by someone else. Enumerations, on the other hand, are “naturally” constant classes and are not at risk of being modified (see the reason in the next section).

Second, the semantics of using int are not clear. For example, if we print only 1 on the console… 2… A number like three, we certainly don’t know what it means.

So someone said, well, let’s use constant characters. You don’t know the semantics, do you? Example implementation code is as follows:

public static final String COLOR_RED = "RED";
public static final String COLOR_BLUE = "BLUE";
public static final String COLOR_GREEN = "GREEN";
Copy the code

The problem with this is that some junior programmers will go against the grain. They may use string values for comparisons instead of enumerating fields directly, as shown in the following example:

public class EnumTest {
    public static final String COLOR_RED = "RED";
    public static final String COLOR_BLUE = "BLUE";
    public static final String COLOR_GREEN = "GREEN";
    public static void main(String[] args) {
        String color = "BLUE";
        if ("BLUE".equals(color)) {
            System.out.println("Blue"); }}}Copy the code

So when we change the values in the enumeration, the program gets cold.

Enumeration usage Scenarios

A common use scenario for enumerations is a singleton, whose complete implementation code is as follows:

public class Singleton {
    // Enumeration types are thread-safe and are loaded only once
    private enum SingletonEnum {
        INSTANCE;
        // Declare a singleton
        private final Singleton instance;
        / / instantiate
        SingletonEnum() {
            instance = new Singleton();
        }
        private Singleton getInstance(a) {
            returninstance; }}// Get instance (singleton)
    public static Singleton getInstance(a) {
        return SingletonEnum.INSTANCE.getInstance();
    }
    private Singleton(a) {}/ / class methods
    public void sayHi(a) {
        System.out.println("Hi,Java."); }}class SingletonTest {
    public static void main(String[] args) { Singleton singleton = Singleton.getInstance(); singleton.sayHi(); }}Copy the code

Because enumerations are only loaded once when the class is loaded, they are thread-safe, which is the main reason the authors of Effective Java strongly recommend using enumerations for singletons.

Knowledge extension

Why are enumerations thread-safe?

Starting with the bytecode that enums eventually generate, let’s first define a simple enumeration class:

public enum ColorEnumTest {
    RED, GREEN, BLANK, YELLOW;
}
Copy the code

We then compile the above code into bytecode as follows:

public final class ColorEnumTest extends java.lang.Enum<ColorEnumTest> {
  public static final ColorEnumTest RED;
  public static final ColorEnumTest GREEN;
  public static final ColorEnumTest BLANK;
  public static final ColorEnumTest YELLOW;
  public static ColorEnumTest[] values();
  public static ColorEnumTest valueOf(java.lang.String);
  static {};
}
Copy the code

As you can see from the above results, enumerations will eventually be compiled as normal classes that are modified with final, and all of their properties will be modified with static and final keywords, so enumerations will be loaded and initialized by the JVM when the project starts. This execution is thread-safe, so enumerations are thread-safe classes.

Tip: Decompilation involves compiling Java code into bytecode (.class) using the Javac command, and then viewing the compiled bytecode using the Javap command.

Enumeration is a little trickier

We use the = = when enumeration comparison is enough, because the enumeration class is created when the application loads, it is not new), and enumerated classes are not allowed to directly in external use the new keyword to create enumerated instances, so when we are in the use of enumeration class essentially only one object, so use the = = when enumeration is enough.

Equlas () : == ();

public final boolean equals(Object other) {
    return this==other;
}
Copy the code

conclusion

In this article we introduced seven ways to use enumerations: constants, switches, adding methods to enumerations, overwriting enumerations, implementing interfaces, organizing enumerations in interfaces, and using enumerations collections. Then we discussed some disadvantages of using ints and strings instead of enumerations: The semantics are unclear, easily modified, and at risk of misuse, so we should use enumerated classes whenever possible. We also talked about the use of enumerated classes – singletons, and why enumerated classes are safe. Finally, we talked about the tips of enumeration comparison. I hope this article will help you.

View & Acknowledgements

www.iteye.com/blog/softbe…

Follow the public account “Java Chinese community” reply “dry goods”, obtain 50 original dry goods Top list.