Why do you recommend enumerations?

Enumeration is a new data type in JDK 1.5. Using enumeration, we can well describe some specific business scenarios, such as spring, summer, autumn and winter of the year, as well as Monday to Sunday of each week, as well as various colors. It can be used to describe some status information, such as error codes.

Enumeration type exists not only in Java language, but also in other languages, such as c# and python. However, I find that few people use enumeration in actual projects, so this article will talk about the relevant contents of enumeration, so as to give friends a general impression of enumeration, In this way, you can at least think of the type of "enumeration" when programming.

The structure of this document is as follows:

7 ways to use enumeration

An important reason why many people don't use enumeration is that they are not familiar with enumeration. Let's start with the seven methods of enumeration.

Usage 1: constant

Before JDK 1.5, we defined constants as public static final, However, with enumeration, we can define these constants as an enumeration class. The implementation code is as follows:

public enum ColorEnum {  
  RED,GREEN,BLANK,YELLOW  
} 

Usage 2: switch

Enumeration is used in switch judgment to improve the readability of the code. The implementation code is as follows:

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

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

Usage 3: add method to enumeration

We can add some methods to enumeration to make enumeration have more features. The implementation code is as follows:

public class EnumTest {
    public static void main(String[] args) {
        ErrorCodeEnum errorCode = ErrorCodeEnum.SUCCESS;
        System.out.println("状态码:" + errorCode.code() + 
                           " 状态信息:" + 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() {
        return code;
    }

    public String msg() {
        return msg;
    }

    public static ErrorCodeEnum getErrorCode(int code) {
        for (ErrorCodeEnum it : ErrorCodeEnum.values()) {
            if (it.code() == code) {
                return it;
            }
        }
        return UNKNowN_ERROR;
    }
}

The results of the above procedures are:

Usage 4: override enumeration method

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

public class EnumTest {
    public static void main(String[] args) {
        ColorEnum colorEnum = ColorEnum.RED;
        System.out.println(colorEnum.toString());
    }
}

enum ColorEnum {
    RED("红色",1),GREEN("绿色",2),BLANK("白色",3),YELLOW("黄色",4);
    //  成员变量
    private String name;
    private int index;

    //  构造方法
    private ColorEnum(String name,int index) {
        this.name = name;
        this.index = index;
    }

    //覆盖方法
    @Override
    public String toString() {
        return this.index + ":" + this.name;
    }
}

The results of the above procedures are:

Usage 5: implement interface

Enumeration classes can be used to implement interfaces, but not to inherit classes, because enumeration inherits Java. Net by default Lang. enum class allows multiple interfaces in Java language, but cannot inherit multiple parent classes. The implementation code is as follows:

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

interface BehavIoUr {
    void print();

    String getInfo();
}

enum ColorEnum implements BehavIoUr {
    RED("红色",4);
    private String name;
    private int index;

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

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

    @Override
    public String getInfo() {
        return this.name;
    }
}

The results of the above procedures are:

Usage 6: organize enumeration classes in the interface

We can create multiple enumeration classes in one interface and use it to realize "polymorphism", that is, we can gather enumeration classes with the same characteristics but slight implementation differences in one interface. The implementation code is as follows:

public class EnumTest {
    public static void main(String[] args) {
        // 赋值第一个枚举类
        ColorInterface colorEnum = ColorInterface.ColorEnum.RED;
        System.out.println(colorEnum);
        // 赋值第二个枚举类
        colorEnum = ColorInterface.NewColorEnum.NEW_RED;
        System.out.println(colorEnum);
    }
}

interface ColorInterface {
    enum ColorEnum implements ColorInterface {
        GREEN,RED
    }
    enum NewColorEnum implements ColorInterface {
        NEW_GREEN,NEW_YELLOW,NEW_RED
    }
}

The results of the above procedures are:

Usage 7: use enumeration collection

Related to enumeration classes in the Java language, there are also two enumeration collection classes, Java util. Enumset and Java util. Enummap, which can achieve more functions.

Using enumset can ensure that elements are not repeated and can obtain elements within the specified range. The example code 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);  // 重复元素
        list.add(ColorEnum.YELLOW);
        list.add(ColorEnum.GREEN);
        // 去掉重复数据
        EnumSet<ColorEnum> enumSet = EnumSet.copyOf(list);
        System.out.println("去重:" + enumSet);

        // 获取指定范围的枚举(获取所有的失败状态)
        EnumSet<ErrorCodeEnum> errorCodeEnums = EnumSet.range(ErrorCodeEnum.ERROR,ErrorCodeEnum.UNKNowN_ERROR);
        System.out.println("所有失败状态:" + errorCodeEnums);
    }
}

enum ColorEnum {
    RED("红色",int index) {
        this.name = name;
        this.index = index;
    }
}

enum ErrorCodeEnum {
    SUCCESS(1000,ERROR(2001,SYS_ERROR(2002,NAMESPACE_NOT_FOUND(2003,String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int code() {
        return code;
    }

    public String msg() {
        return msg;
    }
}

The results of the above procedures are:

Enummap is similar to HashMap, but it is a map collection specially designed for enumeration. Compared with HashMap, it has higher performance because it internally abandons the structure of linked list and red black tree and adopts array as the structure of data storage.

The basic usage examples of enummap are as follows:

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,"红色");
        enumMap.put(ColorEnum.GREEN,"绿色");
        enumMap.put(ColorEnum.BLANK,"白色");
        enumMap.put(ColorEnum.YELLOW,"黄色");
        System.out.println(ColorEnum.RED + ":" + enumMap.get(ColorEnum.RED));
    }
}

enum ColorEnum {
    RED,YELLOW;
}

The results of the above procedures are:

Precautions for use

Alibaba's Java development manual stipulates enumeration as follows. We need to pay attention to it when using it.

If enumeration is not used

Before enumeration was born, that is, before JDK version 1.5, we usually use int constant to represent enumeration. The implementation code is as follows:

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

However, there may be two problems with using int types:

First, the int type itself does not have security. If a programmer lacks a final keyword when defining int, there will be a risk of being modified by others. In contrast, the enumeration class is a constant class, and there is no risk of being modified (see the second half for the reasons);

Second, the semantics of using int type is not clear enough. For example, if we only output 1 when printing on the console 2... 3 such a number, we certainly do not know what it represents.

Then someone said, let's use constant characters. Don't you still know the semantics? The implementation example 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";

However, there is also a problem. Some junior programmers will not play cards according to the routine. They may directly use the value of string for comparison instead of enumerating fields. The implementation example code is as follows:

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("蓝色");
        }
    }
}

In this way, when we modify the values in the enumeration, the program will be cool.

Enumerate usage scenarios

The common use scenario of enumeration is a singleton. Its complete implementation code is as follows:

public class Singleton {
    // 枚举类型是线程安全的,并且只会装载一次
    private enum SingletonEnum {
        INSTANCE;
        // 声明单例对象
        private final Singleton instance;
        // 实例化
        SingletonEnum() {
            instance = new Singleton();
        }
        private Singleton getInstance() {
            return instance;
        }
    }
    // 获取实例(单例对象)
    public static Singleton getInstance() {
        return SingletonEnum.INSTANCE.getInstance();
    }
    private Singleton() {
    }
    // 类方法
    public void sayHi() {
        System.out.println("Hi,Java.");
    }
}
class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        singleton.sayHi();
    }
}

Because enumeration is loaded only once when the class is loaded, it is thread safe, which is the main reason why the author of effective Java strongly recommends using enumeration to implement singleton.

Knowledge expansion

Why is enumeration thread safe?

Let's start with the bytecode finally generated by enumeration. First, let's define a simple enumeration class:

public enum ColorEnumTest {
    RED,YELLOW;
}

Then we compile the above code into bytecode. The details are 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 {};
}

It can be seen from the above results that the enumeration class will eventually be compiled into a common class modified by final, and all its properties will also be modified by static and final keywords. Therefore, the enumeration class will be loaded and initialized by the JVM when the project is started, and the execution process is thread safe, so the enumeration class is also a thread safe class.

Enumeration comparison tips

It is enough for us to use = = when enumerating and comparing, because the enumerating class is created when the program is loaded (it is not new), and the enumerating class is not allowed to directly use the new keyword externally to create enumerating instances. Therefore, when we use the enumerating class, there is essentially only one object, so it is enough to use = = when enumerating and comparing.

And when we look at the enumerating equlas () source code, we will find that it actually directly calls the = = method. The source code is as follows:

public final boolean equals(Object other) {
    return this==other;
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>