枚舉小記錄
隨便寫一個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;
}
參考文檔
總結
需要多度關注一下細節問題…才能更加深入瞭解,使用起來才更加的靈活,你熟悉了纔會有騷操作。
更多汪小哥