Enumerations are a new feature introduced in JDK1.5. A class decorated with the enum keyword is an enumerated class.

The Alibaba development manual has two suggestions for enumerations:

  1. Enumeration class names are suffixed with enums. Enumerator names must be all uppercase and separated by underscores.
  2. If the value of a variable changes only within a fixed range, it is defined as an enum type.

What are the characteristics of an enumeration class

Create an enumeration class of ColorEnum, compile, and decompile to see what happens to it.

public enum ColorEnum {
    RED,GREEN,BULE;
}
Copy the code

Java colorenum.java is compiled to generate the class file, followed by decompilation with javap -p colorenum.class.

The package name is removed and decompiled as follows:

public final class ColorEnum extends Enum{
    public static final ColorEnum GREEN;
    public static final ColorEnum BULE;
    private static final ColorEnum[] $VALUES;
    public static ColorEnum[] values();
    public static ColorEnum valueOf(java.lang.String);
    private ColorEnum(a);
    static {};
}
Copy the code
  1. Enumeration class isfinalModifier, so enumeration classes cannot be inherited;
  2. Enumeration classes inherit by defaultEnumClass, Java does not support multiple inheritance, so enumerated classes cannot inherit from other classes;
  3. The constructor of the enumerated class isprivateModified, so that other classes cannot get objects through constructors;
  4. The member variables of the enumerated class arestaticYou can use the class name. Variable to get an object;
  5. The values() method gets all enumeration instances;
  6. ValueOf (java.lang.string) gets the corresponding instance by name;

Enumeration creates a thread-safe singleton pattern

public enum  SingletonEnum {
    
    INSTANCE;
    
    public void doSomething(a){
        // dosomething...}}Copy the code

A singleton is created, and the object is retrieved by singletonene.instance.

2.1 Serialization makes singleton unsafe

A class may break a singleton if it implements a serialization interface. Each deserialization of a serialized instance object creates a new instance.

Enumeration serialization is guaranteed by the JVM. Each enumeration type and defined enumeration variable is unique to the JVM. Java makes special provisions for the serialization and deserialization of enumeration types: In serialization, Java simply prints the enumeration object’s name property into the result. In deserialization, Java finds the enumeration object by name using the valueOf method of java.lang.Enum. At the same time, the compiler does not allow any customization to this serialization mechanism and disables writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods to ensure that enumeration instances are unique.

2.2 Reflection makes singleton mode unsafe

Forcing calls to private constructors to generate instance objects through reflection makes the singleton pattern unsafe.

Class<? > aClass = Class.forName("xx.xx.xx"); Constructor<? > constructor = aClass.getDeclaredConstructor(String.class); SingletonEnum singleton = (SingletonEnum) constructor.newInstance("Java journey");
Copy the code

But using enumerations to create singletons do not have to worry about this problem at all, to see the source of newInstance!

public T newInstance(Object ... initargs)
    throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
    if(! override) {if(! Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<? > caller = Reflection.getCallerClass(); checkAccess(caller, clazz,null, modifiers); }}// If it is an enumerated type, throw an exception instead of creating an instance object!
    if((clazz.getModifiers() & Modifier.ENUM) ! =0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");
    ConstructorAccessor ca = constructorAccessor;   // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }
    @SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(initargs);
    return inst;
}
Copy the code

Cannot reflectively create enum objects Cannot create instance objects by reflection.

Eliminate if/else by enumeration

If you want to write a set of encryption interface, respectively for the small program, APP and Web end to use, but the three client encryption is not the same. Normally we pass a type type to determine the source, and then call the corresponding decryption method. The code is as follows:

if("WEIXIN".equals(type)){
	// dosomething
}else if("APP".equals(type)){
	// dosomething
}else if("WEB".equals(type)){
	// dosomething
}
Copy the code

Now use enumerations to eliminate the if/else.

Write an encryption interface, encryption and decryption two methods. Then use different algorithms to realize this interface to complete encryption and decryption.

public interface Util {
 
    / / decryption
    String decrypt(a);
    
    / / encryption
    String encrypt(a);
}
Copy the code

Create an enumeration class to implement this interface

public enum UtilEnum implements Util {

    WEIXIN {
        @Override
        public String decrypt(a) {
            return "Decrypt wechat";
        }

        @Override
        public String encrypt(a) {
            return "Wechat encryption";
        }
    },
    APP {
        @Override
        public String decrypt(a) {
            return "App decryption";
        }

        @Override
        public String encrypt(a) {
            return Encryption "app";
        }
    },
    WEB {
        @Override
        public String decrypt(a) {
            return "Web decryption";
        }

        @Override
        public String encrypt(a) {
            return "Web encryption"; }}; }Copy the code

Finally, once you get the type, you simply call the decryption method.

String decryptMessage = UtilEnum.valueOf(type).decrypt();
Copy the code

In the future, if you add another encryption method, you just need to change the enumeration class above, and the business code does not need to change.

These are the two more advanced uses of enumerated classes.

Focus, don’t get lost

If you think the article is good, please pay attention to it, like it, and save it. Your support is the motivation for my creation. Thank you all.

If there is a problem with the article, please don’t be stingy, welcome to point out the message, I will check and modify in time.

If you want to know more about me, you can follow me by searching “Java Journey” on wechat. Reply “1024” to get the learning video and beautiful ebook. Push technical articles at 7:30 every day on time, so that your way to work is not lonely, and there are monthly book activities to help you improve your hard power!