Enum 枚舉小記

枚舉小記錄

隨便寫一個Day的枚舉

public enum Day {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

編譯一下

javac Day.java

反編譯查看

javap  -private Day 

Compiled from "Day.java"
public final class com.wangji92.github.study.other.enums.Day extends java.lang.Enum<com.wangji92.github.study.other.enums.Day> {
  public static final com.wangji92.github.study.other.enums.Day MONDAY;
  public static final com.wangji92.github.study.other.enums.Day TUESDAY;
  public static final com.wangji92.github.study.other.enums.Day WEDNESDAY;
  public static final com.wangji92.github.study.other.enums.Day THURSDAY;
  public static final com.wangji92.github.study.other.enums.Day FRIDAY;
  public static final com.wangji92.github.study.other.enums.Day SATURDAY;
  public static final com.wangji92.github.study.other.enums.Day SUNDAY;
  private static final com.wangji92.github.study.other.enums.Day[] $VALUES;
  public static com.wangji92.github.study.other.enums.Day[] values();
  public static com.wangji92.github.study.other.enums.Day valueOf(java.lang.String);
  private com.wangji92.github.study.other.enums.Day();
  static {};
}

 javap  -private -c  Day
Compiled from "Day.java"
public final class com.wangji92.github.study.other.enums.Day extends java.lang.Enum<com.wangji92.github.study.other.enums.Day> {
  public static final com.wangji92.github.study.other.enums.Day MONDAY;

  public static final com.wangji92.github.study.other.enums.Day TUESDAY;

  public static final com.wangji92.github.study.other.enums.Day WEDNESDAY;

  public static final com.wangji92.github.study.other.enums.Day THURSDAY;

  public static final com.wangji92.github.study.other.enums.Day FRIDAY;

  public static final com.wangji92.github.study.other.enums.Day SATURDAY;

  public static final com.wangji92.github.study.other.enums.Day SUNDAY;

  private static final com.wangji92.github.study.other.enums.Day[] $VALUES;

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

  public static com.wangji92.github.study.other.enums.Day valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class com/wangji92/github/study/other/enums/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/wangji92/github/study/other/enums/Day
       9: areturn

  private com.wangji92.github.study.other.enums.Day();
    Code:
       0: aload_0
       1: aload_1
       2: iload_2
       3: invokespecial #6                  // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
       6: return

  static {};
    Code:
       0: new           #4                  // class com/wangji92/github/study/other/enums/Day
       3: dup
       4: ldc           #7                  // String MONDAY
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field MONDAY:Lcom/wangji92/github/study/other/enums/Day;
      13: new           #4                  // class com/wangji92/github/study/other/enums/Day
      16: dup
      17: ldc           #10                 // String TUESDAY
      19: iconst_1
      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #11                 // Field TUESDAY:Lcom/wangji92/github/study/other/enums/Day;
      26: new           #4                  // class com/wangji92/github/study/other/enums/Day
      29: dup
      30: ldc           #12                 // String WEDNESDAY
      32: iconst_2
      33: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      36: putstatic     #13                 // Field WEDNESDAY:Lcom/wangji92/github/study/other/enums/Day;
      39: new           #4                  // class com/wangji92/github/study/other/enums/Day
      42: dup
      43: ldc           #14                 // String THURSDAY
      45: iconst_3
      46: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      49: putstatic     #15                 // Field THURSDAY:Lcom/wangji92/github/study/other/enums/Day;
      52: new           #4                  // class com/wangji92/github/study/other/enums/Day
      55: dup
      56: ldc           #16                 // String FRIDAY
      58: iconst_4
      59: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      62: putstatic     #17                 // Field FRIDAY:Lcom/wangji92/github/study/other/enums/Day;
      65: new           #4                  // class com/wangji92/github/study/other/enums/Day
      68: dup
      69: ldc           #18                 // String SATURDAY
      71: iconst_5
      72: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      75: putstatic     #19                 // Field SATURDAY:Lcom/wangji92/github/study/other/enums/Day;
      78: new           #4                  // class com/wangji92/github/study/other/enums/Day
      81: dup
      82: ldc           #20                 // String SUNDAY
      84: bipush        6
      86: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      89: putstatic     #21                 // Field SUNDAY:Lcom/wangji92/github/study/other/enums/Day;
      92: bipush        7
      94: anewarray     #4                  // class com/wangji92/github/study/other/enums/Day
      97: dup
      98: iconst_0
      99: getstatic     #9                  // Field MONDAY:Lcom/wangji92/github/study/other/enums/Day;
     102: aastore
     103: dup
     104: iconst_1
     105: getstatic     #11                 // Field TUESDAY:Lcom/wangji92/github/study/other/enums/Day;
     108: aastore
     109: dup
     110: iconst_2
     111: getstatic     #13                 // Field WEDNESDAY:Lcom/wangji92/github/study/other/enums/Day;
     114: aastore
     115: dup
     116: iconst_3
     117: getstatic     #15                 // Field THURSDAY:Lcom/wangji92/github/study/other/enums/Day;
     120: aastore
     121: dup
     122: iconst_4
     123: getstatic     #17                 // Field FRIDAY:Lcom/wangji92/github/study/other/enums/Day;
     126: aastore
     127: dup
     128: iconst_5
     129: getstatic     #19                 // Field SATURDAY:Lcom/wangji92/github/study/other/enums/Day;
     132: aastore
     133: dup
     134: bipush        6
     136: getstatic     #21                 // Field SUNDAY:Lcom/wangji92/github/study/other/enums/Day;
     139: aastore
     140: putstatic     #1                  // Field $VALUES:[Lcom/wangji92/github/study/other/enums/Day;
     143: return
}

枚舉更深認識–> 以上信息看到了什麼?

  • enum 這個是一個語法糖,所有的都繼承了java.lang.Enum

public final class com.wangji92.github.study.other.enums.Day extends java.lang.Enum<com.wangji92.github.study.other.enums.Day>

  • 枚舉中的字段都變成了靜態常量

public static final com.wangji92.github.study.other.enums.Day MONDAY;

  • 當前class 有個私有的變量集合 $VALUES

    private static final com.wangji92.github.study.other.enums.Day[] $VALUES;

  • static 靜態塊 初始化當前所有枚舉

    並通過構造調用父類構造函數。

enum 超類

這是所有Java語言枚舉類型的公共基類。有關枚舉的更多信息,包括編譯器合成的隱式聲明方法的描述。
Note that when using an enumeration type as the type of a set or as the type of the keys in a map, specialized and efficient {@linkplain java.util.EnumSet set} and {@linkplain java.util.EnumMap map} implementations are available.


package java.lang;
public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
    /**
     * The name of this enum constant, as declared in the enum declaration.
     * Most programmers should use the {@link #toString} method rather than
     * accessing this field.
     */
    private final String name;

    public final String name() {
        return name;
    }
    /**
     * The ordinal of this enumeration constant (its position
     * in the enum declaration, where the initial constant is assigned
     * an ordinal of zero).
     *
     * Most programmers will have no use for this field.  It is designed
     * for use by sophisticated enum-based data structures, such as
     * {@link java.util.EnumSet} and {@link java.util.EnumMap}.
     */
    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();
    }

    /**
     * Returns the enum constant of the specified enum type with the
     * specified name.  The name must match exactly an identifier used
     * to declare an enum constant in this type.  (Extraneous whitespace
     * characters are not permitted.)
     *
     * <p>Note that for a particular enum type {@code T}, the
     * implicitly declared {@code public static T valueOf(String)}
     * method on that enum may be used instead of this method to map
     * from a name to the corresponding enum constant.  All the
     * constants of an enum type can be obtained by calling the
     * implicit {@code public static T[] values()} method of that
     * type.
     *
     * @param <T> The enum type whose constant is to be returned
     * @param enumType the {@code Class} object of the enum type from which
     *      to return a constant
     * @param name the name of the constant to return
     * @return the enum constant of the specified enum type with the
     *      specified name
     * @throws IllegalArgumentException if the specified enum type has
     *         no constant with the specified name, or the specified
     *         class object does not represent an enum type
     * @throws NullPointerException if {@code enumType} or {@code name}
     *         is null
     * @since 1.5
     */
    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() { }

    /**
     * prevent default deserialization
     */
    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");
    }
}

簡單看

簡單看一下內部的實現是否感覺和我們平時的使用差不多的,這裏的name 就是枚舉自己定義的那個名稱,然後oder 就是順序而已… 並沒有什麼差別對不對。

valueOf的實現

子類的也是調用父類的來實現的,枚舉自己本身也主要依靠class中的類的方法來實現的。

 public static com.wangji92.github.study.other.enums.Day valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class com/wangji92/github/study/other/enums/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/wangji92/github/study/other/enums/Day
       9: areturn
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);
}

class 中的方法
 /**
     * Returns a map from simple name to enum constant.  This package-private
     * method is used internally by Enum to implement
     * {@code public static <T extends Enum<T>> T valueOf(Class<T>, String)}
     * efficiently.  Note that the map is returned by this method is
     * created lazily on first use.  Typically it won't ever get created.
     */
    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;
   }

// 通過調用子類的靜態方法values 獲取當前所有的枚舉值得信息
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;
    }

參考文檔

總結

需要多度關注一下細節問題…才能更加深入瞭解,使用起來才更加的靈活,你熟悉了纔會有騷操作。
更多汪小哥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章