Java enumeration type (enum)

enumeration implementation principle

package com.own.learn.jdk.enum1;



public enum Day {
    MONDAY("monday"), TUESDAY("TUESDAY"), WEDNESDAY("WEDNESDAY"),
    THURSDAY("THURSDAY"), FRIDAY("FRIDAY"), SATURDAY("SATURDAY"), SUNDAY("SUNDAY");

    private String name;

    Day(String name) {
        this.name = name;
    }
}

Take out the decompiled code:

javap -c com/own/learn/jdk/enum1/Day.class

public final class com.own.learn.jdk.enum1.Day extends java.lang.Enum<com.own.learn.jdk.enum1.Day> {
  public static final com.own.learn.jdk.enum1.Day MONDAY;

  public static final com.own.learn.jdk.enum1.Day TUESDAY;

  public static final com.own.learn.jdk.enum1.Day WEDNESDAY;

  public static final com.own.learn.jdk.enum1.Day THURSDAY;

  public static final com.own.learn.jdk.enum1.Day FRIDAY;

  public static final com.own.learn.jdk.enum1.Day SATURDAY;

  public static final com.own.learn.jdk.enum1.Day SUNDAY;

  public static com.own.learn.jdk.enum1.Day[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[Lcom/own/learn/jdk/enum1/Day;
       3: invokevirtual #2                  // Method "[Lcom/own/learn/jdk/enum1/Day;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[Lcom/own/learn/jdk/enum1/Day;"
       9: areturn

  public static com.own.learn.jdk.enum1.Day valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class com/own/learn/jdk/enum1/Day
       2: aload_0
       3: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #4                  // class com/own/learn/jdk/enum1/Day
       9: areturn

  static {};
    Code:
       0: new           #4                  // class com/own/learn/jdk/enum1/Day
       3: dup
       4: ldc           #8                  // String MONDAY
       6: iconst_0
       7: ldc           #9                  // String monday
       9: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      12: putstatic     #11                 // Field MONDAY:Lcom/own/learn/jdk/enum1/Day;
      15: new           #4                  // class com/own/learn/jdk/enum1/Day
      18: dup
      19: ldc           #12                 // String TUESDAY
      21: iconst_1
      22: ldc           #12                 // String TUESDAY
      24: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      27: putstatic     #13                 // Field TUESDAY:Lcom/own/learn/jdk/enum1/Day;
      30: new           #4                  // class com/own/learn/jdk/enum1/Day
      33: dup
      34: ldc           #14                 // String WEDNESDAY
      36: iconst_2
      37: ldc           #14                 // String WEDNESDAY
      39: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      42: putstatic     #15                 // Field WEDNESDAY:Lcom/own/learn/jdk/enum1/Day;
      45: new           #4                  // class com/own/learn/jdk/enum1/Day
      48: dup
      49: ldc           #16                 // String THURSDAY
      51: iconst_3
      52: ldc           #16                 // String THURSDAY
      54: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      57: putstatic     #17                 // Field THURSDAY:Lcom/own/learn/jdk/enum1/Day;
      60: new           #4                  // class com/own/learn/jdk/enum1/Day
      63: dup
      64: ldc           #18                 // String FRIDAY
      66: iconst_4
      67: ldc           #18                 // String FRIDAY
      69: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      72: putstatic     #19                 // Field FRIDAY:Lcom/own/learn/jdk/enum1/Day;
      75: new           #4                  // class com/own/learn/jdk/enum1/Day
      78: dup
      79: ldc           #20                 // String SATURDAY
      81: iconst_5
      82: ldc           #20                 // String SATURDAY
      84: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
      87: putstatic     #21                 // Field SATURDAY:Lcom/own/learn/jdk/enum1/Day;
      90: new           #4                  // class com/own/learn/jdk/enum1/Day
      93: dup
      94: ldc           #22                 // String SUNDAY
      96: bipush        6
      98: ldc           #22                 // String SUNDAY
     100: invokespecial #10                 // Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
     103: putstatic     #23                 // Field SUNDAY:Lcom/own/learn/jdk/enum1/Day;
     106: bipush        7
     108: anewarray     #4                  // class com/own/learn/jdk/enum1/Day
     111: dup
     112: iconst_0
     113: getstatic     #11                 // Field MONDAY:Lcom/own/learn/jdk/enum1/Day;
     116: aastore
     117: dup
     118: iconst_1
     119: getstatic     #13                 // Field TUESDAY:Lcom/own/learn/jdk/enum1/Day;
     122: aastore
     123: dup
     124: iconst_2
     125: getstatic     #15                 // Field WEDNESDAY:Lcom/own/learn/jdk/enum1/Day;
     128: aastore
     129: dup
     130: iconst_3
     131: getstatic     #17                 // Field THURSDAY:Lcom/own/learn/jdk/enum1/Day;
     134: aastore
     135: dup
     136: iconst_4
     137: getstatic     #19                 // Field FRIDAY:Lcom/own/learn/jdk/enum1/Day;
     140: aastore
     141: dup
     142: iconst_5
     143: getstatic     #21                 // Field SATURDAY:Lcom/own/learn/jdk/enum1/Day;
     146: aastore
     147: dup
     148: bipush        6
     150: getstatic     #23                 // Field SUNDAY:Lcom/own/learn/jdk/enum1/Day;
     153: aastore
     154: putstatic     #1                  // Field $VALUES:[Lcom/own/learn/jdk/enum1/Day;
     157: return
}

Convert to code is probably like this:

package com.own.learn.jdk.enum1;

public final class DayEnum extends Enum {
    public static DayEnum MONDAY;

    public static DayEnum TUESDAY;

    public static DayEnum WEDNESDAY;

    public static DayEnum THURSDAY;

    public static DayEnum FRIDAY;

    public static DayEnum SATURDAY;

    public static DayEnum SUNDAY;
    private static DayEnum $VALUES[];

    static {
        MONDAY = new DayEnum("MONDAY", 0);
        TUESDAY = new DayEnum("TUESDAY", 1);
        WEDNESDAY = new DayEnum("WEDNESDAY", 2);
        THURSDAY = new DayEnum("THURSDAY", 3);
        FRIDAY = new DayEnum("FRIDAY", 4);
        SATURDAY = new DayEnum("SATURDAY", 5);
        SUNDAY = new DayEnum("SUNDAY", 6);
        $VALUES = (new DayEnum[]{
                MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
        });
    }


    public DayEnum[] values() {
        return (DayEnum[]) $VALUES.clone();
    }

    public DayEnum valueOf(String name) {
        return (DayEnum) Enum.valueOf(com.own.learn.jdk.enum1.DayEnum.class, name);

    }

    protected DayEnum(String name, int ordinal) {
        super(name, ordinal);
    }

    @Override
    public String toString() {
        return super.toString();
    }
}

Enum类

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {

    private final String name;


    public final String name() {
        return name;
    }


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


    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);
    }

    /**
     * enum classes cannot have finalize methods.
     */
    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");
    }
}
  1. ordinal: The number from 0 to Integer.Max_value is only used in EnumSet and EnumMap. The default is 0.
  2. equals method: `return this==other. The enumeration is a constant
  3. compareTo: the default comparison is: ordinal
  4. valueOf:enumType.enumConstantDirectory().get(name);
  Map<String, T> enumConstantDirectory() {
        if (enumConstantDirectory == null) {
            T[] universe = getEnumConstantsShared();
            if (universe == null)
                throw new IllegalArgumentException(
                    getName() + " is not an enum type");
            Map<String, T> m = new HashMap<>(2 * universe.length);
            for (T constant : universe)
                m.put(((Enum<?>)constant).name(), constant);
            enumConstantDirectory = m;
        }
        return enumConstantDirectory;
    }
 T[] getEnumConstantsShared() {
        if (enumConstants == null) {
            if (!isEnum()) return null;
            try {
                final Method values = getMethod("values");
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                values.setAccessible(true);
                                return null;
                            }
                        });
                @SuppressWarnings("unchecked")
                T[] temporaryConstants = (T[])values.invoke(null);
                enumConstants = temporaryConstants;
            }
            // These can happen when users concoct enum-like classes
            // that don't comply with the enum spec.
            catch (InvocationTargetException | NoSuchMethodException |
                   IllegalAccessException ex) { return null; }
        }
        return enumConstants;
    }
    private volatile transient T[] enumConstants = null;

by calling the values ​​method to get the enumerated array, and then converting it into the map

enumeration of the advanced usage

向The enum class addition method and the custom constructor

public enum Day {
    MONDAY("monday"), TUESDAY("TUESDAY"), WEDNESDAY("WEDNESDAY"),
    THURSDAY("THURSDAY"), FRIDAY("FRIDAY"), SATURDAY("SATURDAY"), SUNDAY("SUNDAY");

    private String name;

    Day(String name) {
        this.name = name;
    }
}

enum class define the abstract method

package com.own.learn.jdk.enum1;

public enum  DayAbstractMethod {

    FOOD {
        @Override
        public void printName() {
            System.out.println(" name is " + name());
        }
    };

    public abstract void printName();


    public static void main(String[] args) {

        DayAbstractMethod.FOOD.printName();
    }
}

enum class and interface

package com.own.learn.jdk.enum1;

interface Start{
    void start();
}

interface End{
    void end();
}
public enum  EnumInterface implements Start, End{
    TEST1
    ;


    @Override
    public void start() {

    }

    @Override
    public void end() {

    }
}

and the singleton pattern

public enum  EnumSingleton {

    INSTANCE;
    public void otherMethods(){
        //todo sth
        System.out.println("Something");
    }
}

should be related to the class initialization lock