枚舉編譯
- 創建一個類:FruitEnum繼承自java.lang.Enum
- 定義的枚舉被聲明為public static final類型常量
- FruitEnum$VALUES數組,保存常量APPLE和ORANGE
- 創建兩個對象,常量引用這個兩個對象
- 兩個靜態方法:
- values()拷貝一份數組
- valueOf(String),調用java.lang.Enum中的valueOf
- 注意:這里的valueOf(String)只有一個參數
總結:每一個枚舉類型極其定義的枚舉變量在JVM中都是唯一的,(類型不可繼承,構造方法私有,編譯器構造,不支持clone)
序列化
枚舉常量和其他對象序列化不同,序列化的枚舉類型,只包含name,而filed值不在序列化文件里。
- 序列化時,ObjectOutputStream寫入name方法返回的值(就是字符串)。
- 反序列化時,ObjectInputStream從流中讀取name值,然后通過java.lang.Enum.valueOf方法獲取這個枚舉常量。編譯器是不允許任何對這種序列化機制的定制的,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。
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 const " + enumType +"." + name);
}
private volatile transient Map<String, T> enumConstantDirectory = null;
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;
}
枚舉的組織:
1.接口
2.枚舉的枚舉
3.枚舉嵌套枚舉
public enum Meal {
APPTIZER(Food.Appetizer.class), MAINCOURSE(Food.MainCourse.class);
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP;
}
enum MainCourse implements Food {
Dumpling, Noodles;
}
}
private Food[] values;
private Meal(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}
void show() {
for (Food value : values) {
System.out.println(value);
}
}
public static void main(String[] args) {
System.out.println(Meal.APPTIZER.name());
}
}