Java基礎系列-Enum深入解析


原創(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關鍵字定義一個枚舉留瞳,編譯之后,編譯器會對其進行加工骚秦,具體如下:

  1. 編譯成為class類型她倘,并繼承自Enum
  2. 添加靜態(tài)的values方法,用于獲取所有枚舉值的數組
  3. 添加valueOf方法作箍,實現Enum中的valueOf方法硬梁,可以根據具體的枚舉值名稱字符串獲取對應的枚舉值
  4. 添加私有構造器,其中調用Enum中定義的唯一的構造器
  5. 定義靜態(tài)常量枚舉值
  6. 添加靜態(tài)塊為這些靜態(tài)枚舉常量賦值

通過上面一些列加工之后胞得,枚舉類被解析為一個普通的類荧止,類名不變。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末懒震,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子嗤详,更是在濱河造成了極大的恐慌个扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葱色,死亡現場離奇詭異递宅,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門办龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烘绽,“玉大人,你說我怎么就攤上這事俐填“步樱” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵英融,是天一觀的道長盏檐。 經常有香客問我,道長驶悟,這世上最難降的妖魔是什么胡野? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任痕鳍,我火速辦了婚禮硫豆,結果婚禮上,老公的妹妹穿的比我還像新娘笼呆。我一直安慰自己熊响,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布抄邀。 她就那樣靜靜地躺著耘眨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪境肾。 梳的紋絲不亂的頭發(fā)上剔难,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音奥喻,去河邊找鬼偶宫。 笑死,一個胖子當著我的面吹牛环鲤,可吹牛的內容都是我干的纯趋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼冷离,長吁一口氣:“原來是場噩夢啊……” “哼吵冒!你這毒婦竟也來了?” 一聲冷哼從身側響起西剥,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤痹栖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瞭空,有當地人在樹林里發(fā)現了一具尸體揪阿,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡疗我,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了南捂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吴裤。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溺健,靈堂內的尸體忽然破棺而出麦牺,到底是詐尸還是另有隱情,我是刑警寧澤矿瘦,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布枕面,位于F島的核電站,受9級特大地震影響缚去,放射性物質發(fā)生泄漏潮秘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一易结、第九天 我趴在偏房一處隱蔽的房頂上張望枕荞。 院中可真熱鬧,春花似錦搞动、人聲如沸躏精。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矗烛。三九已至,卻和暖如春箩溃,著一層夾襖步出監(jiān)牢的瞬間瞭吃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工涣旨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歪架,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓霹陡,卻偏偏與公主長得像和蚪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烹棉,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345