原創(chuàng)文章畜普,轉載請標注出處:《Java基礎系列-Enum深入解析》
一、概述
枚舉就是一個語法糖效果护侮。
定義一個枚舉敌完,其實就是定義一個繼承抽象類Enum的類。
了解了Enum羊初,就能了解枚舉滨溉。
二、Enum解析
2.1 接口
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {}
枚舉類實現了Comparable和Serializable接口,那么也就意味著业踏,每個枚舉類都擁有比較(有序)和序列化功能禽炬。
2.2 屬性
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表示的是枚舉值的序號腹尖。
其作用后面再說
2.3 構造器
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就是為了繼承它的子類(我們定義的各種枚舉)來調用的伐脖。
2.4 equals方法
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
public final boolean equals(Object other) {
return this==other;
}
}
默認的equals方法底層就是使用==實現的热幔,所以在枚舉的比較使用equals和==都是可以的。前提是沒有在枚舉類中重寫equals方法讼庇。
我們可以在自定義的枚舉類中重寫該方法绎巨,來實現我們自己的比較方式。
2.5 禁用的功能
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");
}
}
這四個方法均是被禁用的方法:
- 克氯渥摹:目的為了保證單例唯一
- finalize:禁用終引用
- 序列化中禁用readObject和readObjectNoData方法:目的為了保證單例唯一
2.6 compareTo方法
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中的方法场勤。用于定義比較的方式,可以看出這里是使用枚舉值的序號作為比較條件的歼跟。
2.7 方法
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關鍵字定義一個枚舉留瞳,編譯之后,編譯器會對其進行加工骚秦,具體如下:
- 編譯成為class類型她倘,并繼承自Enum
- 添加靜態(tài)的values方法,用于獲取所有枚舉值的數組
- 添加valueOf方法作箍,實現Enum中的valueOf方法硬梁,可以根據具體的枚舉值名稱字符串獲取對應的枚舉值
- 添加私有構造器,其中調用Enum中定義的唯一的構造器
- 定義靜態(tài)常量枚舉值
- 添加靜態(tài)塊為這些靜態(tài)枚舉常量賦值
通過上面一些列加工之后胞得,枚舉類被解析為一個普通的類荧止,類名不變。