原創文章,轉載請標註出處:http://www.javashuo.com/article/p-sorpszpw-dx.htmlhtml
枚舉就是一個語法糖效果。java
定義一個枚舉,其實就是定義一個繼承抽象類Enum的類。數組
瞭解了Enum,就能瞭解枚舉。this
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {}
枚舉類實現了Comparable和Serializable接口,那麼也就意味着,每一個枚舉類都擁有比較(有序)和序列化功能。code
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { private final String name; private final int ordinal; public final String name() { return name; } public final int ordinal() { return ordinal; } }
這兩個屬性是枚舉的內置屬性,name表示的是枚舉值的名稱,ordinal表示的是枚舉值的序號。htm
其做用後面再說blog
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } }
Enum中只有這一個構造器,其申明爲protected就是爲了繼承它的子類(咱們定義的各類枚舉)來調用的。繼承
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { public final boolean equals(Object other) { return this==other; } }
默認的equals方法底層就是使用==實現的,因此在枚舉的比較使用equals和==都是能夠的。前提是沒有在枚舉類中重寫equals方法。接口
咱們能夠在自定義的枚舉類中重寫該方法,來實現咱們本身的比較方式。字符串
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { protected final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } protected final void finalize() { } 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"); } }
這四個方法均是被禁用的方法:
序列化中禁用readObject和readObjectNoData方法:目的爲了保證單例惟一
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { public final int compareTo(E o) { Enum<?> other = (Enum<?>)o; Enum<E> self = this; if (self.getClass() != other.getClass() && // optimization self.getDeclaringClass() != other.getDeclaringClass()) throw new ClassCastException(); return self.ordinal - other.ordinal; } }
這是實現了接口Comparable中的方法。用於定義比較的方式,能夠看出這裏是使用枚舉值的序號做爲比較條件的。
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { 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關鍵字定義一個枚舉,編譯以後,編譯器會對其進行加工,具體以下:
經過上面一些列加工以後,枚舉類被解析爲一個普通的類,類名不變。