Android之使用枚舉利弊及替代方案

知識點:

1. 不使用枚舉enum引起的類型不安全問題畜埋;
2. 使用枚舉enum的利弊阔籽;
3. 利用@interface+@IntDef/@StringDef替代enum;
4. 新名詞記錄{typeof吼鳞,@IntDef/@StringDef奄抽,@interface}

概述

Enum 是 java 中一種包含固定常數(shù)的類型蔼两,當(dāng)我們需要預(yù)先定義一些值時,我們使用 Enum逞度,這樣做通常為了在編譯時期避免接受額外常量引起的錯誤额划。

而且,Enum 增加了APK 的大小档泽,比常量多5到10倍的內(nèi)存占用锁孟,這是關(guān)于應(yīng)用性能的最佳實踐彬祖。

為什么要使用枚舉?

舉一個例子品抽,例如我們要為一個bean賦值一個person的性別屬性储笑,因為性別只有男女,所以我們通常的做法是定義兩個整型int圆恤,來區(qū)分男女”性別突倍。

  public class SexTest {
        private final int MAN = 101, WOMEN = 102;
        private int sex;

        //設(shè)置性別
        public void setSex(int sex) {
            this.sex = sex;
        }

        //獲取性別
        public String getSex() {
            if (MAN == sex) return "男";
            if (WOMEN == sex) return "女";
            return "未知";
        }

        public static void main(String[] args) {
            setSex(101);
            int sex = getSex();
            System.out.println("sex: " + sex);
            //輸出:sex: 男
            //設(shè)置為102入?yún)?            setSex(102);
            String resultSex = getSex();
            System.out.println("resultSex: " + resultSex);
            //輸出:resultSex: 未知
        }
    }

由上面的例子可以看出,當(dāng)我們定義了一個男女的final整型作為入?yún)r盆昙,不一定保證入?yún)⒌亩际俏覀兿胍娜雲(yún)⒂鹄@里就有一個類型不安全”的問題出現(xiàn)。而枚舉就可以解決這個問題淡喜。

例如秕磷,首先定義一個枚舉類,里面有男炼团,女兩個枚舉常量澎嚣。

    public class SexTest {

        public static enum Sex {
            MAN, WOMEN
        }

        private Sex sex;

        //設(shè)置性別
        public void setSex(Sex sex) {
            this.sex = sex;
        }

        //獲取性別
        public String getSex() {
            if (Sex.MAN == sex) return "男";
            if (Sex.WOMEN == sex) return "女";
            return "未知";
        }

        public static void main(String[] args) {
            //這里的入?yún)⒈仨殲镾ex枚舉類中的其中一個枚舉常量
            //絕對不允許輸入沒有再Sex枚舉里面定義的常量
            setSex(Sex.MAN);
            String resultSex = getSex();
            System.out.println("resultSex: " + resultSex);
            //輸出:resultSex: 男
        }
    }

所以我們可以看到,我們利用枚舉瘟芝,在setSex()方法里面對入?yún)⒆隽嗣杜eSex的限制易桃,對于我們想輸入任何非枚舉類Sex里面定義的枚舉常量,編譯都是不能通過的锌俱。這就很好的限制了入?yún)⒒靵y的問題晤郑。

但是,“every coin has two sides”贸宏。馬克思告訴我們造寝,一切都是矛盾體,事物必然有好的一面也有不好的一面吭练。對于枚舉同樣適用诫龙,下面我們來看下適用枚舉的缺點。


使用 Enum 的缺點

每一個枚舉值都是一個對象线脚,在使用它時會增加額外的內(nèi)存消耗,所以枚舉相比與 Integer 和 String 會占用更多的內(nèi)存赐稽。

較多的使用 Enum 會增加 DEX 文件的大小,會造成運行時更多的開銷叫榕,使我們的應(yīng)用需要更多的空間浑侥。

如果你的應(yīng)用使用很多的 Enum ,最好使用Integer 或 String 替代他們,但是這樣還會有問題晰绎。

既然都說到這個份上了寓落,那么有什么比較好的解決方法呢?


解決方案

既然是因為參數(shù)的類型太泛了造成的類型不安全荞下,那么我只要將參數(shù)限定在某一個類型集合里面伶选,不就大功告成了史飞?!

是滴仰税,一下就是要將的@IntDef/@StringDef + @interface來進行限定參數(shù)构资。

首先你要在build.gradle文件中添加依賴

dependencies { compile ‘com.android.support:support-annotations:24.2.0’ }

然后再使用,代碼如下:

    public class SexTest {
        private final int MAN = 101, WOMEN = 102;

        @IntDef({MAN, WOMEN}) //限定為MAN,WOMEN
        @Retention(RetentionPolicy.SOURCE) //表示注解所存活的時間,在運行時,而不會存在. class 文件.
        public @interface Sex { //接口陨簇,定義新的注解類型
        }

        public void setSex(@Sex int sex) {
            this.sex = sex;

        public static void main(String[] args) {
            setSex(MAN);
        }
    }

如果我們嘗試在調(diào)用setSex()方法的時候吐绵,傳入不在限定之內(nèi)的值,那么編譯就不會通過河绽,有錯誤提示己单。同理,我們也可以使用@StringDef耙饰。


總結(jié)

可以看到纹笼,如果不適用枚舉,將會帶來類型不安全的問題苟跪。一般情況下廷痘,我們在很多地方都會使用到枚舉,因為方便和簡潔削咆。但是使用枚舉也會產(chǎn)生占用內(nèi)存過高等情況牍疏。所以我們可以有了自定義的方案,來限定我們使用的類型范圍拨齐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鳞陨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞻惋,更是在濱河造成了極大的恐慌厦滤,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歼狼,死亡現(xiàn)場離奇詭異掏导,居然都是意外死亡,警方通過查閱死者的電腦和手機羽峰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門趟咆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人梅屉,你說我怎么就攤上這事值纱。” “怎么了坯汤?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵虐唠,是天一觀的道長。 經(jīng)常有香客問我惰聂,道長疆偿,這世上最難降的妖魔是什么咱筛? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮杆故,結(jié)果婚禮上迅箩,老公的妹妹穿的比我還像新娘。我一直安慰自己处铛,他們只是感情好沙热,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罢缸,像睡著了一般篙贸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枫疆,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天爵川,我揣著相機與錄音,去河邊找鬼息楔。 笑死寝贡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的值依。 我是一名探鬼主播圃泡,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愿险!你這毒婦竟也來了颇蜡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤辆亏,失蹤者是張志新(化名)和其女友劉穎风秤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扮叨,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缤弦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了彻磁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碍沐。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衷蜓,靈堂內(nèi)的尸體忽然破棺而出累提,到底是詐尸還是另有隱情,我是刑警寧澤恍箭,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布刻恭,位于F島的核電站瞧省,受9級特大地震影響扯夭,放射性物質(zhì)發(fā)生泄漏鳍贾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一交洗、第九天 我趴在偏房一處隱蔽的房頂上張望骑科。 院中可真熱鬧,春花似錦构拳、人聲如沸咆爽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斗埂。三九已至,卻和暖如春凫海,著一層夾襖步出監(jiān)牢的瞬間呛凶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工行贪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留漾稀,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓建瘫,卻偏偏與公主長得像崭捍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子啰脚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

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