• The enumeration
    • Introduction to the
    • How to use
      • 1. Grammar
      • 2. For example
      • 3. Underlying principles
      • 4. Uniqueness of enumeration
    • Commonly used method
    • Enumeration of member variables and methods
    • The resources

The enumeration

Introduction to the

Enumerations are new in Java 5. They are special classes that typically represent a set of constants. They can use constructors (which must be private), define member variables and methods, and implement one or more interfaces, just like normal classes

How to use

1. Grammar
  • Declare that enumeration classes must be usedenumTo implement, the concise syntax is as follows:
enum-modifiers enum enumname {
        enum-body,
}
Copy the code
  • Description:
    • enum-modifiersAccess modifier
    • enumnameDeclare the name of the enumerated class
    • enum-bodyRepresents a member of the enumeration
2. For example
  • Declare an enumeration class named Color
Public enum Color {BLACK, WHITE} // 2. Public static void main(String[] args) {system.out.println (color.black); // BLACK } }Copy the code
3. Underlying principles
  • So let’s go throughjadTool to decompile Color class, throughjad -sjava Color.classDecompile a copyJava file
Public final class Color extends Enum {public final class Color extends Enum {public final class Color extends Enum {public final class Color extends Enum Color[] values() { return (Color[]) $VALUES.clone(); } public static Color valueOf(String name) {return (Color) Enum. ValueOf (em/Color, name); } // Private constructor private Color(String name, int ordinal) {super(name, ordinal); } public static final Color BLACK public static final Color BLACK; public static final Color WHITE; // private static final Color $VALUES[]; Static {BLACK = new Color("BLACK", 0); static {BLACK = new Color("BLACK", 0); WHITE = new Color("WHITE", 1); $VALUES = (new Color[]{ BLACK, WHITE }); }}Copy the code
  • From decompilationColorClass as can be seen in theEnum keywordClass, for variables defined in the first line (before the first semicolon, to be exact), will generate oneColor instance, and it is initialized in the static domain, and the static domain is initialized in the class loading phase, soEnumeration objects are thread-safe and guaranteed by the JVM

Ps: Here I think of eight singleton implementations, one of which is the implementation of enum. At that time, it was very difficult to understand how it creates objects. Is it just a constant? The general code is as follows

public enum Singleton { INSTANCE; public void doWhatever() { // todo ... }}Copy the code

Public static final Singleton INSTANCE = new public static final Singleton INSTANCE = new Singleton()), and since it is controlled by the JVM, it has one and only one object instance, which is extremely elegant

This approach is highly recommended by Effective Java and Java & Patterns. What are the benefits of implementing enumerations this way?

The Effective Java approach is functionally similar to the public domain approach, but it is much simpler, provides a serialization mechanism for free, and absolutely prevents multiple instantiations, even in the face of complex serialization or reflection attacks. Although this approach is not yet widely adopted, enumerations of single-element types have emerged as the best way to implement Singleton. — Effective Java Chinese Edition 2

In Java and Patterns, the authors write that using enumerations to implement singleton control is simpler, provides a serialization mechanism for free, and is fundamentally guaranteed by the JVM to absolutely prevent multiple instances. It is a simpler, more efficient, and safer way to implement singleton control.

4. Uniqueness of enumeration

An enumeration type has instances that, at the time of writing, are determined not to be created by any other means, and enumeration variables have one and only one corresponding instance in the JVM.

  1. Class load time to ensure thread-safe

As you can see from the Color class, the Color object is created in a static domain and initialized at class load time. The JVM guarantees thread-safety, which ensures that multiple instances of the Color object are not created incorrectly due to concurrent requests.

  1. Special handling of serialization prevents new objects from being created during deserialization

We know that once Serializable is implemented, each call to readObject() returns a newly created object when deserializing, unlike enumeration, where Java simply outputs the name property of the enumeration object to the result. In deserialization, Enum valueOf() is used to find enumeration objects by name. At the same time, the compiler does not allow any customization to this serialization, so the writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods are disabled


   public static <T extends Enum<T>> T valueOf(Class
       
         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);
   }
   /** * prevent default deserialization */
   private void readObject(ObjectInputStream in) throws IOException,
       ClassNotFoundException {
       throw new InvalidObjectException("can't deserialize enum");
   }

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

Copy the code
  1. There are constructors, can not normally new out of the object

Even if we don’t use itprivateThe default access modifier is stillprivate

  1. Cannot clone objects using the clone() method
 
   /** * Throws CloneNotSupportedException. This guarantees that enums * are never cloned, which is necessary to preserve their "singleton" * status. */
   protected final Object clone(a) throws CloneNotSupportedException {
       throw new CloneNotSupportedException();
   }  
   
Copy the code
  1. Enumeration objects cannot be created by reflection

Enumeration type, which at the JVM level disallows the construction of an enumeration instance through reflection. If you attempt to create an enumeration instance through reflection, Cannot reflectively create enum Objects will be reported

Static void reflectTest() throws Exception {// Obtain the Class<? > cls = Class.forName("com.xiao.basetest.base.enums.Color"); // Get the color Constructor<? > constructor = cls.getDeclaredConstructor(String.class, int.class); / / get access to the constructor. SetAccessible (true); // Instantiate Object reflectColor = constructor.newinstance ("name", 0); } / / an error Exception in the thread "is the main" Java. Lang. IllegalArgumentException: Cannot reflectively create enum objects at java.lang.reflect.Constructor.newInstance(Constructor.java:417) at Main.reflect(Main.java:24) at Main.main(Main.java:13)Copy the code

Commonly used method

Method names describe
values() Returns all members of an enumerated type as an array
valueOf() Converts a plain string to an enumeration instance
compareTo() Compares the order in which two enumerators are defined
ordinal() Gets the index location of an enumerator
  1. values()Loop over member variables and useordinal()Output index value
public static void main(String[] args) { for (Color value : Color.values()) {system.out.println (" +value.ordinal()+"); }} // Result: The current index is 0, and the data is BLACK. The current index is 1, and the data is WHITECopy the code
  1. throughvalueof()Get the enumeration instance and usecompareTo()Compare definition order
public enum Color { BLACK, WHITE, YELLOW; } class Test { public static void main(String[] args) { Color color = Color.valueOf("WHITE"); compare(color); } public static void compare(Color color){ for (Color value : Color.values()) {system.out.println (Color +" +value+"); }}} Result: The comparison result of WHITE and BLACK is 1, the comparison result of WHITE and WHITE is 0, the comparison result of WHITE and YELLOW is -1Copy the code

Enumeration of member variables and methods

  • In addition to enumeration constants, enums are a complete class that can also be definedMember variablesWrite your ownA constructorAs well asMembers of the methodAnd evenImplementing an interface.

It is important to note that an enumerated class cannot inherit from another class because at compile time it already inherits Enum, and Java cannot inherit more than one class

Public enum Color implements Runnable {WHITE(" BLACK ",1), BLACK(" WHITE ",2), YELLOW(" YELLOW ",3); private final String value; Private final Integer index; Private Color(String value,Integer index) {this.value = value; this.index = index; } public void draw() {system.out.println (" draw "+ value); } @override public String toString() {return "hello I'm "+value+", my index is "+index; Override public void run() {// todo... } } class Test { public static void main(String[] args) { for (Color value : Color.values()) { System.out.println(value); }}} result: Hello I'm black, my index is 1 Hello I'm white, my index is 2 Hello I'm yellow, my index is 3Copy the code
  • Now that we’re talking about methods, what happens if we use abstract methods in enumerations? And after the abstract method is introducedEnumeration policy patternRelated instructions

When a particular constant type is associated with a method or behavior in a body, consider using enumerations to implement the policy pattern when there is a relationship between data and behavior

Suppose we define an abstract method in an enumeration class, where should it be implemented, certainly in an enumeration instance variable, and must be implemented


public enum Operation {
    PLUS{
        @Override
        public int apply(int a, int b) {
            return a+b;
        }
    },
    MINUS{
        @Override
        public int apply(int a, int b) {
            returna-b; }};public abstract int apply(int a,int b);

    public static void main(String[] args) {
        System.out.println(Operation.PLUS.apply(1.2)); }}Copy the code

This mode is applicable when the input data is the same, but different operations need to be performed

Complex enumeration

EnumSet,EnumMap, portal, portal, portal, portal, portal

The resources

CSDN -Java enumeration tutorial – Enumeration book -Java enumeration comprehensive interpretation

This article is published by OpenWrite!