不一樣的Java Enum

Emum是在Java5中引入的新特性牛曹,從那開始似袁,它被廣泛的用在不同的Java應(yīng)用中存璃,相比于C和C++的Enum淋叶,Java的Enum功能更加強(qiáng)大阎曹。但是很多開發(fā)人員暫時(shí)還沒意識(shí)到它的強(qiáng)大之處伪阶,在Enum的一些細(xì)節(jié)問題上把握的還不到位。Enum的特性及相關(guān)資料可以整理出一本書也不為過处嫌,這里簡(jiǎn)單對(duì)Enum做個(gè)大概栅贴。主要講解以下幾個(gè)方面。


Java Enum
  1. Enum的介紹
  2. Enum的特性
  3. Enum的用法
  4. Enum的一些面試題
  5. Enum用法建議

什么是Enum

Enum是一個(gè)Java的關(guān)鍵字熏迹,用于表示一個(gè)固定的常用值檐薯。例如,每周的天數(shù)注暗,每年的月數(shù)等坛缕。Enum是一種類型,就像Class和Interface可以用于定義一系列的Enum常量

Enum的特性

  • Enum常量隱式的加上了static和final捆昏,一旦被創(chuàng)建就無法修改
  • Enum提供了是類型安全的(type-safe)
  • Enum隱式的加上了values()方法赚楚,返回一個(gè)數(shù)組包含所有的Enum常量
  • 兩個(gè)Enum常量可以使用 ==equals()方法比較
  • Enum可以用在switch語句中,就像int骗卜,String宠页。
  • Enum有自己的名稱空間
  • Enum可以實(shí)現(xiàn)Java接口
  • 可以在Enum中定義構(gòu)造器

Enum的用法

1 . Enum的聲明,Enum可以聲明在一個(gè)類之外或者在類內(nèi)部寇仓,但是不能在方法中举户。

// 外部聲明Enum
enum Color {
    RED,GREEN,BLUE;
}
public class Test
{
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}
//內(nèi)部聲明Enum
public class Test
{
    enum Color
    {
        RED, GREEN, BLUE;
    }
    
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}

2 . 在創(chuàng)建Enum常量的時(shí)候可以指定值,但是這個(gè)時(shí)候你需要定義一個(gè)成員變量構(gòu)造器遍烦。構(gòu)造器必須是private的俭嘁,不然會(huì)報(bào)編譯錯(cuò)誤。

public enum Currency {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
    private int value;

    private Currency(int value) {
        this.value = value;
    }
}

3 . 使用==equals比較兩個(gè)enum
因?yàn)閑num對(duì)象都是繼承自Enum類的服猪,可以看到Enum中的equals方法為供填。
建議使用==方法,直接比較應(yīng)該比調(diào)用方法的速度更快一些蔓姚。另外==號(hào)還能防止NullPointerException

    public final boolean equals(Object other) {
        return this==other;
    }

4 . 對(duì)Enum進(jìn)行排序的時(shí)候捕虽,使用compareTo方法慨丐。

    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;
    }

5 .有兩個(gè)新的集合類EnumMapEnumSet 坡脐,他們兩個(gè)是對(duì)Set和Map的高性能實(shí)現(xiàn),當(dāng)有機(jī)會(huì)使用它們的時(shí)候房揭,盡量使用它們备闲。

Enum面試問題

  1. 說說Enum的繼承
    所有的enums隱式的extend了java.lang.Enum類,因?yàn)橐粋€(gè)類只能extend一個(gè)父親捅暴,所以enum不能extend其它的類恬砂。
    但是Enum可以實(shí)現(xiàn)許多接口

  2. Enum的values,ordinal,valueOf方法
    enums默認(rèn)有values(),ordinal()和valueOf()方法蓬痒。
    values()方法返回所有在enum中定義的常量值泻骤,以數(shù)組形式返回。
    ordinal()方法返回每個(gè)常量的索引下標(biāo),就像數(shù)組的下標(biāo)
    valueOf()方法傳入字符串參數(shù)狱掂,如果enum中存在對(duì)應(yīng)字符串的常量值演痒,則返回對(duì)應(yīng)的enum常量

// 案例代碼
enum Color
{
    RED, GREEN, BLUE;
}

public class EnumLearn
{
    public static void main(String[] args)
    {
        
        Color arr[] = Color.values();        
        for (Color col : arr)
        {
            System.out.println(col + " at index "
                    + col.ordinal());
        }
        System.out.println(Color.valueOf("RED"));
    }
}

//輸出
RED at index 0
GREEN at index 1
BLUE at index 2
RED

3 . Enum的構(gòu)造器特性
enum可以有構(gòu)造器方法,它的構(gòu)造器方法會(huì)在enum類型加載的時(shí)候趋惨,按常量的個(gè)數(shù)順序的執(zhí)行
我們不能直接創(chuàng)建enum對(duì)象鸟顺,因此我們也不能直接調(diào)用enum的構(gòu)造器方法,構(gòu)造器方法必須是private的

//案例代碼
enum AccountType implements Serializable,Cloneable
{
    SAVING, FIXED, CURRENT;
    private AccountType()
    {
        System.out.println("It is a account type");
    }
}
class EnumOne
{
    public static void main(String[]args)
    {
        System.out.println(AccountType.FIXED);

    }
}
//輸出結(jié)果
It is a account type
It is a account type
It is a account type
FIXED

4 . Enum的單例模式優(yōu)缺點(diǎn)
參考《Effitive Java》器虾,優(yōu)點(diǎn)大于缺點(diǎn)讯嫂,因?yàn)閑num是線程安全的,因此我們無需考慮單例模式的雙重檢查兆沙。主要原因:

  • enum的單例模式簡(jiǎn)單
  • enum是線程安全的
  • enum的單例模式自己處理序列化 *
// Enum的單例模式 VS 傳統(tǒng)雙重檢查的單例模式
//單例模式欧芽,僅需使用一行代碼.
// EasySingleton.INSTANCE,enum中也可以寫其他方法
public enum EasySingleton{
    INSTANCE;
}

//傳統(tǒng)模式
public class DoubleCheckedLockingSingleton{
     private volatile DoubleCheckedLockingSingleton INSTANCE;
  
     private DoubleCheckedLockingSingleton(){}
  
     public DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //  二次檢查
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

5 . Enum的==equals的區(qū)別葛圃。
前面有提到渐裸。

6 . 我們能使用構(gòu)造方法創(chuàng)建enum實(shí)例嗎?
不能装悲,enum的構(gòu)造方法必須是私有的昏鹃。

Enum的用法建議

在能想到使用Enum的時(shí)候可以考慮使用Enum。

  1. 使用Enum代替定義的相關(guān)int類型常量
  2. 能用到EnumSet和EnumMap的時(shí)候使用它們诀诊,后面會(huì)再說明它們兩個(gè)的用法
  3. 表示固有的對(duì)象最好使用Enum

最后

看一些Java相關(guān)的面試題洞渤,發(fā)現(xiàn)Enum相關(guān)問題出現(xiàn)頻率挺高的,在這里對(duì)enum用法做個(gè)整理属瓣。希望能幫助到大家

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末载迄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抡蛙,更是在濱河造成了極大的恐慌护昧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粗截,死亡現(xiàn)場(chǎng)離奇詭異惋耙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)熊昌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門绽榛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人婿屹,你說我怎么就攤上這事灭美。” “怎么了昂利?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵届腐,是天一觀的道長(zhǎng)铁坎。 經(jīng)常有香客問我,道長(zhǎng)犁苏,這世上最難降的妖魔是什么厢呵? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮傀顾,結(jié)果婚禮上襟铭,老公的妹妹穿的比我還像新娘。我一直安慰自己短曾,他們只是感情好寒砖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嫉拐,像睡著了一般哩都。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上婉徘,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天漠嵌,我揣著相機(jī)與錄音,去河邊找鬼盖呼。 笑死儒鹿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的几晤。 我是一名探鬼主播约炎,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蟹瘾!你這毒婦竟也來了圾浅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤憾朴,失蹤者是張志新(化名)和其女友劉穎狸捕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體众雷,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灸拍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了报腔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片株搔。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剖淀,死狀恐怖纯蛾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纵隔,我是刑警寧澤翻诉,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布炮姨,位于F島的核電站,受9級(jí)特大地震影響碰煌,放射性物質(zhì)發(fā)生泄漏舒岸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一芦圾、第九天 我趴在偏房一處隱蔽的房頂上張望蛾派。 院中可真熱鬧,春花似錦个少、人聲如沸洪乍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壳澳。三九已至,卻和暖如春茫经,著一層夾襖步出監(jiān)牢的瞬間巷波,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工卸伞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抹镊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓荤傲,卻偏偏與公主長(zhǎng)得像髓考,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弃酌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法氨菇,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法,并非Fa...
    孫小磊閱讀 1,967評(píng)論 0 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法妓湘,類相關(guān)的語法查蓉,內(nèi)部類的語法,繼承相關(guān)的語法榜贴,異常的語法豌研,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 時(shí)間的齒輪永遠(yuǎn)在向前滾動(dòng)著,而他們終將活在我的記憶里唬党! 他曾是我初中時(shí)的少年鹃共,溫文爾雅是我對(duì)他的第一印象;而后便是...
    往逝閱讀 130評(píng)論 0 1
  • 一點(diǎn)也不好吃J还啊K !蓝纲!不好吃R趺稀I稳摇! 抬頭發(fā)現(xiàn)一個(gè)好看的角度永丝! 今天一天把規(guī)定的該做的事情都解決好了锹漱,這是我感覺很滿意...
    無所說_閱讀 145評(píng)論 0 0
  • “兩個(gè)人睡一開始總是相互擁著或者一方的手臂給另一方當(dāng)枕頭,整晚睡得香甜慕嚷。但手總會(huì)麻哥牍。如果突然分開了,一個(gè)人睡喝检,無論...
    段童閱讀 334評(píng)論 0 2