枚举小记录
随便写一个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;
}
参考文档
总结
需要多度关注一下细节问题…才能更加深入了解,使用起来才更加的灵活,你熟悉了才会有骚操作。
更多汪小哥