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

参考文档

总结

需要多度关注一下细节问题…才能更加深入了解,使用起来才更加的灵活,你熟悉了才会有骚操作。
更多汪小哥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值