Java SE foundation consolidation (V): Enumeration

Enumeration in many programming languages have, such as C / C ++, but Java until JDK1.5 only increase this characteristic, as to why so late, I do not know. What is it that enumeration? There are the following definition in Wikipedia: in mathematics and computer science theory, a set of enumeration is a list of some programs for all members of a finite set of sequences, or a particular type of object count. Such as day of the week SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY and so on.

The 1 Java enum

1.1 simple to use

Java components are various classes, enumeration is no exception. To create the enumerated class, the class keyword you want to just replace the general category into the enum keyword, as shown here:

public enum ColorEnum {

    RED("RED", 0),
    BLUE("BLUE", 1),
    BLACK("BLACK",2),
    WHITE("WHITE", 3);

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

    private String name;

    private int code;

    //getter and setter
}
复制代码

Enum class can have member variables, constructors, instance methods, static methods, but only constructor is private, ie the external program can not use the constructor to construct enumerate instances, can only be created inside instance of the class, such as RED ( "RED", 0) wording is calling constructor creates enumerate instances, and this example is a single case, which is why some articles say that using enumeration to achieve singleton pattern is the easiest (though most simple, but not the most practical, because of the poor readability). Write a class, be sure to use the following code shows the use of enumeration class:

public class Test {


    public static void main(String[] args) {
        System.out.println(ColorEnum.BLACK);        //直接调用实例
        System.out.println(ColorEnum.BLACK.getName()); //调用实例的getName()方法
        System.out.println(ColorEnum.BLACK.getCode()); //调用实例的getCode()方法
        System.out.println(ColorEnum.valueOf("BLACK")); //valueOf()方法根据枚举的名字获取枚举实例

        System.out.println("----------------------------");
        for (ColorEnum colorEnum : ColorEnum.values()) {  //values()方法返回该枚举类的所有枚举实例
            System.out.println(colorEnum.getName());
            System.out.println(colorEnum.ordinal());    //ordinal返回该枚举实例在枚举类中声明的顺序,从0开始
        }
    }
}

复制代码

Notes written more clearly, the only confusing is the valueOf (String) method, which accepts a parameter is the name of an enumeration instance, pay attention to here is not the name refers to the member variable name, but the name of the instance itself, For example RED in ColorEnum in ( "RED", 0) statement, the outermost RED is the name of the instance itself, the string "RED" just a member variable of the enumeration class, do not understand it does not matter here, and so will look at the source code when I will understand.

Abstract methods 1.2 enumeration

In addition to simply use outside, we can also join in the enumeration class abstract method, each instance of this abstract methods must be implemented, otherwise it will fail to compile as follows:

//其他代码和原先完全一样
RED("RED", 0) {
    @Override
    public void abstractMethod() {
        System.out.println("RED's method");
    }
},
BLUE("BLUE", 1) {
    @Override
    public void abstractMethod() {
        System.out.println("BLUE's method");
    }
},
BLACK("BLACK",2) {
    @Override
    public void abstractMethod() {
        System.out.println("BLACK's method");
    }
},
WHITE("WHITE", 3) {
    @Override
    public void abstractMethod() {
        System.out.println("WHITE's method");
    }
};

public abstract void abstractMethod();
复制代码

Code declares abstractMethod () abstract method, each enumeration instance must implement this method and enumerate each instance can have its own implementation, which is a manifestation enumeration class flexibility. This feature is very useful in some scenarios, such as if there is a class used to represent enumerated four arithmetic operations, the abstract method, which has two parameters, then the difference arithmetic operation can be achieved according to their different operational characteristics .

Enumeration but it is still a lot of flexible usage, which is not much to say.

2 Enum Class Resolution

Enum class is the parent class of all enumeration class, and implements the Comparable Serializable interface, comparable and has the ability to be serializable. Its source code is shown below:

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
   
    //name字段表示枚举实例的名字
    private final String name;

    public final String name() {
        return name;
    }
	
	//ordinal字段表示枚举实例在枚举类中声明的顺序,从0开始
    private final int ordinal;
    
    public final int ordinal() {
        return ordinal;
    }
    
    //构造器
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    public String toString() {
        return name;
    }

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

    public final int hashCode() {
        return super.hashCode();
    }

	//默认不支持clone
    protected final Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    public final int compareTo(E o) {
        Enum<?> other = (Enum<?>)o;
        Enum<E> self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

    @SuppressWarnings("unchecked")
    public final Class<E> getDeclaringClass() {
        Class<?> clazz = getClass();
        Class<?> zuper = clazz.getSuperclass();
        return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
    }

    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }

    protected final void finalize() { }

	//默认不支持反序列化,反序列化会破坏单例模式
    private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
        throw new InvalidObjectException("can't deserialize enum");
    }

    private void readObjectNoData() throws ObjectStreamException {
        throw new InvalidObjectException("can't deserialize enum");
    }
}

复制代码

Let's look at two member variables name and ordinal, name is the name of the previously mentioned enumerate instances, ordinal enumeration order is declared in the instance of the enumeration class, starting at 0. Then is the valueOf () method to obtain the corresponding enumeration instance according to enumerate instances of the class object names and enumerate instances, when we used did not pass enumType, because when you create an enumeration class, Java help us joined a heavy-duty version, we generally use the heavy-duty version. Finally, take a look at readObject () method, by default, enumerate instances can be serialized, but can not be deserialized because the deserialization when calls readObject method, by default, this method throws an exception directly stop deserialization, we can open the switch by deserialized override this method, but be careful, because the characteristics of a single embodiment deserialization operation may destroy enumerated example, it might cause the virtual machine enumeration example is not unique.

Other methods such as equal, compareTo what not to say, it's all routine.

3 Summary

Enumeration is a very important component, very powerful and flexible, but many developers may look down on him, but think it is a statement of some enumeration constants only. This really is the most fundamental role of the enumeration, but in fact, Java enumeration there are many other powerful features, for example, can declare abstract methods, we can easily guarantee thread safety, ensure a single case, and so on.

Guess you like

Origin juejin.im/post/5d6e80905188251ff57fa172