亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發(fā)設計 > 正文

關(guān)于Java中枚舉Enum的深入剖析

2019-11-14 08:45:14
字體:
供稿:網(wǎng)友

學習java的同學注意了?。。?nbsp;學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:183993990  我們一起學Java!

在編程語言中我們,都會接觸到枚舉類型,通常我們進行有窮的列舉來實現(xiàn)一些限定。Java也不例外。Java中的枚舉類型為Enum,本文將對枚舉進行一些比較深入的剖析。

什么是Enum

Enum是自Java 5 引入的特性,用來方便Java開發(fā)者實現(xiàn)枚舉應用。一個簡單的Enum使用如下。

// ColorEnum.javapublic enum ColorEmun {    RED,    GREEN,    YELLOW}public void setColorEnum(ColorEmun colorEnum) {    //some code here}setColorEnum(ColorEmun.GREEN);

為什么會有Enum

在Enum之前的我們使用類似如下的代碼實現(xiàn)枚舉的功能.

public static final int COLOR_RED = 0;public static final int COLOR_GREEN = 1;public static final int COLOR_YELLOW = 2;public void setColor(int color) {    //some code here}//調(diào)用setColor(COLOR_RED)

然而上面的還是有不盡完美的地方

setColor(COLOR_RED)與setColor(0)效果一樣,而后者可讀性很差,但卻可以正常運行setColor方法可以接受枚舉之外的值,比如setColor(3),這種情況下程序可能出問題

概括而言,傳統(tǒng)枚舉有如下兩個弊端

安全性可讀性,尤其是打印日志時

因此Java引入了Enum,使用Enum,我們實現(xiàn)上面的枚舉就很簡單了,而且還可以輕松避免傳入非法值的風險.

枚舉原理是什么

Java中Enum的本質(zhì)其實是在編譯時期轉(zhuǎn)換成對應的類的形式。

首先,為了探究枚舉的原理,我們先簡單定義一個枚舉類,這里以季節(jié)為例,類名為Season,包含春夏秋冬四個枚舉條目.

public enum Season {    SPRING,    SUMMER,    AUTUMN,    WINTER}

然后我們使用javac編譯上面的類,得到class文件.

javac Season.java

然后,我們利用反編譯的方法來看看字節(jié)碼文件究竟是什么.這里使用的工具是javap的簡單命令,先列舉一下這個Season下的全部元素.

company javap SeasonWarning: Binary file Season contains com.company.SeasonCompiled from "Season.java"public final class com.company.Season extends java.lang.Enum<com.company.Season> {  public static final com.company.Season SPRING;  public static final com.company.Season SUMMER;  public static final com.company.Season AUTUMN;  public static final com.company.Season WINTER;  public static com.company.Season[] values();  public static com.company.Season valueOf(java.lang.String);  static {};}

從上反編譯結(jié)果可知

java代碼中的Season轉(zhuǎn)換成了繼承自的java.lang.enum的類既然隱式繼承自java.lang.enum,也就意味java代碼中,Season不能再繼承其他的類Season被標記成了final,意味著它不能被繼承

static代碼塊

使用javap具體反編譯class文件,得到靜態(tài)代碼塊相關(guān)的結(jié)果為

static {};    Code:       0: new           #4                  // class com/company/Season       3: dup       4: ldc           #7                  // String SPRING       6: iconst_0       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V      10: putstatic     #9                  // Field SPRING:Lcom/company/Season;      13: new           #4                  // class com/company/Season      16: dup      17: ldc           #10                 // String SUMMER      19: iconst_1      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V      23: putstatic     #11                 // Field SUMMER:Lcom/company/Season;      26: new           #4                  // class com/company/Season      29: dup      30: ldc           #12                 // String AUTUMN      32: iconst_2      33: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V      36: putstatic     #13                 // Field AUTUMN:Lcom/company/Season;      39: new           #4                  // class com/company/Season      42: dup      43: ldc           #14                 // String WINTER      45: iconst_3      46: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V      49: putstatic     #15                 // Field WINTER:Lcom/company/Season;      52: iconst_4      53: anewarray     #4                  // class com/company/Season      56: dup      57: iconst_0      58: getstatic     #9                  // Field SPRING:Lcom/company/Season;      61: aastore      62: dup      63: iconst_1      64: getstatic     #11                 // Field SUMMER:Lcom/company/Season;      67: aastore      68: dup      69: iconst_2      70: getstatic     #13                 // Field AUTUMN:Lcom/company/Season;      73: aastore      74: dup      75: iconst_3      76: getstatic     #15                 // Field WINTER:Lcom/company/Season;      79: aastore      80: putstatic     #1                  // Field $VALUES:[Lcom/company/Season;      83: return}

其中

0~52為實例化SPRING, SUMMER, AUTUMN, WINTER53~83為創(chuàng)建Season[]數(shù)組$VALUES,并將上面的四個對象放入數(shù)組的操作.

values方法

values方法的的返回值實際上就是上面$VALUES數(shù)組對象

swtich中的枚舉

在Java中,switch-case是我們經(jīng)常使用的流程控制語句.當枚舉出來之后,switch-case也很好的進行了支持.

比如下面的代碼是完全正常編譯,正常運行的.

public static void main(String[] args) {        Season season = Season.SPRING;        switch(season) {            case SPRING:                System.out.println("It's Spring");                break;            case WINTER:                System.out.println("It's Winter");                break;            case SUMMER:                System.out.println("It's Summer");                break;            case AUTUMN:                System.out.println("It's Autumn");                break;        }    }

不過,通常情況下switch-case支持類似int的類型,那么它是怎么做到對Enum的支持呢,我們反編譯上述方法看一下字節(jié)碼的真實情況.

public static void main(java.lang.String[]);    Code:       0: getstatic     #2                  // Field com/company/Season.SPRING:Lcom/company/Season;       3: astore_1       4: getstatic     #3                  // Field com/company/Main$1.$SwitchMap$com$company$Season:[I       7: aload_1       8: invokevirtual #4                  // Method com/company/Season.ordinal:()I      11: iaload      12: tableswitch   { // 1 to 4                     1: 44                     2: 55                     3: 66                     4: 77               default: 85          }      44: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;      47: ldc           #6                  // String It's Spring      49: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      52: goto          85      55: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;      58: ldc           #8                  // String It's Winter      60: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      63: goto          85      66: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;      69: ldc           #9                  // String It's Summer      71: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      74: goto          85      77: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;      80: ldc           #10                 // String It's Autumn      82: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      88: return

注意上面代碼塊有這樣的一段代碼

8: invokevirtual #4                  // Method com/company/Season.ordinal:()I

事實果真如此,在switch-case中,還是將Enum轉(zhuǎn)成了int值(通過調(diào)用Enum.oridinal()方法)

枚舉與混淆

在Android開發(fā)中,進行混淆是我們在發(fā)布前必不可少的工作,混下后,我們能增強反編譯的難度,在一定程度上保護了增強了安全性.

而開發(fā)人員處理混淆更多的是將某些元素加入不混淆的名單,這里枚舉就是需要排除混淆的.

在默認的混淆配置文件中,已經(jīng)加入了關(guān)于對枚舉混淆的處理

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}

關(guān)于為什么要保留values()方法和valueOf()方法,請參考文章讀懂 Android 中的代碼混淆 關(guān)于枚舉的部分

使用proguard優(yōu)化

使用Proguard進行優(yōu)化,可以將枚舉盡可能的轉(zhuǎn)換成int。配置如下

-optimizations class/unboxing/enum

確保上述代碼生效,需要確proguard配置文件不包含-dontoptimize指令。

當我們使用gradlew打包是,看到類似下面的輸出,即Number of unboxed enum classes:1代表已經(jīng)將一個枚舉轉(zhuǎn)換成了int的形式。

Optimizing...  Number of finalized classes:                 0   (disabled)  Number of unboxed enum classes:              1  Number of vertically merged classes:         0   (disabled)  Number of horizontally merged classes:       0   (disabled)

枚舉單例

單例模式是我們在日常開發(fā)中可謂是最常用的設計模式.

然后要設計好單例模式,無非考慮一下幾點

確保只有唯一實例,不多創(chuàng)建多余實例確保實例按需創(chuàng)建.

因此傳統(tǒng)的做法想要實現(xiàn)單例,大致有一下幾種

餓漢式加載懶漢式synchronize和雙重檢查利用java的靜態(tài)加載機制

相比上述的方法,使用枚舉也可以實現(xiàn)單例,而且還更加簡單.

public enum AppManager {    INSTANCE;    private String tagName;    public void setTag(String tagName) {        this.tagName = tagName;    }    public String getTag() {        return tagName;    }}

調(diào)用起來也更加簡單

AppManager.INSTANCE.getTag();

枚舉如何確保唯一實例

因為獲得實例只能通過AppManager.INSTANCE

下面的方式是不可以的

AppManager appManager = new AppManager(); //compile error

關(guān)于單例模式,可以閱讀單例這種設計模式了解更多。

(Android中)該不該用枚舉

既然上面提到了枚舉會轉(zhuǎn)換成類,這樣理論上造成了下面的問題

增加了dex包的大小,理論上dex包越大,加載速度越慢同時使用枚舉,運行時的內(nèi)存占用也會相對變大

關(guān)于上面兩點的驗證,秋百萬已經(jīng)做了詳細的論證,大家可以參考這篇文章《Android 中的 Enum 到底占多少內(nèi)存?該如何用?》

關(guān)于枚舉是否使用的結(jié)論,大家可以參考

如果你開發(fā)的是Framework不建議使用enum如果是簡單的enum,可以使用int很輕松代替,則不建議使用enum另外,如果是Android中,可以使用下面介紹的枚舉注解來實現(xiàn)。除此之外,我們還需要對比可讀性和易維護性來與性能進行衡量,從中進行做出折中

在Android中的替代

Android中新引入的替代枚舉的注解有IntDef和StringDef,這里以IntDef做例子說明一下.

public class Colors {    @IntDef({RED, GREEN, YELLOW})    @Retention(RetentionPolicy.SOURCE)    public @interface LightColors{}    public static final int RED = 0;    public static final int GREEN = 1;    public static final int YELLOW = 2;}聲明必要的int常量聲明一個注解為LightColors使用@IntDef修飾LightColors,參數(shù)設置為待枚舉的集合使用@Retention(RetentionPolicy.SOURCE)指定注解僅存在與源碼中,不加入到class文件中

比如我們用來標注方法的參數(shù)

private void setColor(@Colors.LightColors int color) {        Log.d("MainActivity", "setColor color=" + color);}

調(diào)用的該方法的時候

setColor(Colors.GREEN);

以上就是我對Java中enum的一些深入的剖析,歡迎大家不吝賜教。

學習Java的同學注意了?。?! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:183993990  我們一起學Java!


上一篇:centos 安裝 eclipse

下一篇:lucene總結(jié)

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
久久精品国产99久久6| 欧美人与动xxxxz0oz| 日韩高清在线电影| 超碰免费在线播放| 一色屋成人免费精品网站| 亚洲欧美另类在线视频| 亚洲天堂一区在线| 国语自产精品视频在免费| 尤物视频..com| 91国偷自产一区二区开放时间| 国产男女免费视频| 精品久久久免费视频| www.久久久久久久久久| 一区二区三区| 国产精品1luya在线播放| 黄色大片免费看| 欧美6699在线视频免费| 亚洲精品自拍区在线观看| 成人欧美一区二区三区在线播放| 欧美一区二区三区播放老司机| 亚洲一二三在线观看| 国产精品suv一区二区三区| 7777精品伊人久久久大香线蕉超级流畅| 国产欧美日韩一级| 成人永久免费视频| 日韩成人网免费视频| 久久日韩精品| 嫩草av久久伊人妇女超级a| av在线播放国产| 国产又爽又黄又嫩又猛又粗| 日韩欧美不卡| 成人看片毛片免费播放器| 亚洲一区二区三区四区| 99久久久久国产精品| 欧美男同视频网| 欧美黑人极品猛少妇色xxxxx| 91在线导航| 嗯啊主人调教在线播放视频| 日韩欧美亚洲国产精品字幕久久久| 88国产精品欧美一区二区三区| 一区二区中文字幕在线观看| 欧美国产二区| 国产麻豆91视频| 久久久久国产精品www| 中文 欧美 日韩| 欧洲精品99毛片免费高清观看| 麻豆国产欧美日韩综合精品二区| 亚洲女人天堂a在线播放| 国产精品外围在线观看| 欧美两根一起进3p做受视频| 欧美日韩激情小视频| 日韩视频一区在线观看| 男男一级淫片免费播放| 天天想你在线观看完整版电影免费| 久久精品日韩精品| 欧美激情在线免费| 在线日本视频| 91精品国产综合久久久蜜臀图片| 奇米777影视成人四色| 国产女优在线播放| 另类专区欧美蜜桃臀第一页| 午夜剧场在线免费观看| 欧美一二三四区在线| 一区二区三区免费播放| 日韩视频一区二区三区在线播放免费观看| 精品国偷自产在线视频| 欧美在线观看一区二区三区| 亚洲第一福利社区| 日本xxxx裸体xxxx| 国产在线播放精品| 97成人免费视频| 91久久黄色| 青青青视频在线免费观看| 日韩 欧美 自拍| 手机在线不卡av| 成人av婷婷| 91精品国产一区二区在线观看| 麻豆蜜桃在线观看| 国产日韩欧美制服另类| 日韩中文首页| 好吊视频一区二区三区| 午夜性色福利视频| 中文字幕在线观看一区二区三区| 国产午夜精品视频免费不卡69堂| 99国产精品久久久久老师| 丝袜制服一区二区三区| 911国产精品| 超清福利视频| 亚洲男人的天堂一区二区| 国产精品一区二区久激情瑜伽| 日韩视频123| 婷婷中文字幕一区三区| 99久久国产综合精品五月天喷水| 在线观看免费视频一区二区三区| 电影天堂av在线| 国产婷婷成人久久av免费高清| 色综合久久综合网| 又嫩又硬又黄又爽的视频| 日日噜噜夜夜狠狠久久丁香五月| av久久久久久| 最好看的2019的中文字幕视频| 久草热视频在线观看| 日韩三级在线观看| 夜色av.com| 欧美日韩久久久| 亚洲国产一区二区精品视频| 亚洲乱码国产乱码精品精的特点| 91丨九色丨蝌蚪丨老板| 成人免费乱码大片a毛片软件| 9.1国产丝袜在线观看| 精品免费国产一区二区三区四区| 国产精品一区二区三| 日韩超碰人人爽人人做人人添| 特黄视频在线观看| 91精品在线看| 国产精品主播视频| 色哟哟国产精品色哟哟| 丰满少妇又爽又紧又丰满电影| 秋霞成人影院| 色哟哟免费在线观看| 伊人国产在线观看| 国产视频一区二区视频| 中文字幕在线2019| 国产精品美女久久久久久2018| 日韩欧美xxxx| 综合网日日天干夜夜久久| 蜜桃av免费看| 精品国产a一区二区三区v免费| 成人h小游戏| 欲求不满中文字幕| 一区二区三区视频免费观看| 久久久久一本一区二区青青蜜月| 久久久噜噜噜久久中文字免| 欧美一级淫片videoshd| xxx成人少妇69| 黄网站在线观| 日韩欧美国产成人| 在线播放日本| 春意影院午夜免费入口| 午夜精品福利在线| 一起草在线视频| 久久久久亚洲精品| 亚洲精品水蜜桃| 国产精品19p| 久久久久九九九九| 国产一区二区三区在线免费观看| 欧美一区1区三区3区公司| 五月婷婷狠狠干| 欧美交a欧美精品喷水| 国产激情久久久久久熟女老人av| 亚洲jjzzjjzz在线观看| 欧美 日韩 国产一区| 91爱爱小视频k| 99热这里只有精品在线| 国产美女亚洲精品7777| 亚洲不卡1卡2卡三卡2021麻豆| 俺去啦俺在线观看| 99re这里只有精品视频首页| 久久69国产一区二区蜜臀| 久久99久久亚洲国产| 一夜七次郎国产精品亚洲| av电影免费在线观看| 激情小说网站亚洲综合网| 色综合久久一区二区三区| a天堂中文在线88| 国产精品电影网站| 亚洲一区二区三区四区五区午夜| 成人在线小视频| 久久国产精品首页| 午夜久久黄色| 国产精品在线| 粗暴蹂躏中文一区二区三区| 亚洲一区999| 亚洲 欧美 自拍偷拍| ●精品国产综合乱码久久久久| 黄色日韩网站视频| 亚洲在线电影| 亚欧日韩另类中文欧美| 国产真人无遮挡作爱免费视频| 九九九精品视频| 亚洲产国偷v产偷v自拍涩爱| 精品国产sm最大网站免费看| 老司机精品影院| 国产精品精品视频| 超碰97国产精品人人cao| 极品色影院av| 欧美久久一级| 国产午夜精品一区在线观看| 亚洲人成免费网站| 亚洲午夜久久久影院| 成人性生交大片免费看中文视频| 国产在线更新| 怡红院视频网站| 精品人妻一区二区三区日产乱码| 国产一区二区三区中文| 久久久久亚洲av无码专区| 国产婷婷色综合av蜜臀av| 国产精品免费看久久久香蕉| 国产在亚洲线视频观看| 欧美日韩国产在线播放| 高清国产mv在线观看| 国产精选在线观看91| 久久av在线播放| 亚洲自偷自拍熟女另类| 奇米色在线视频| 国产亚洲精品午夜高清影院| 久久这里精品国产99丫e6| 日韩一区二区在线视频| 一级淫片免费看| 成人黄页毛片网站| 国产精品久久久久久久精| 久草免费福利视频| 公侵犯人妻一区二区三区| 亚洲人metart人体| www.成人av| 精品欧美日韩精品| 久草在线资源站资源站| 91麻豆国产精品| 老熟妇一区二区| 日韩成人三级| 欧美一区二区影院| 在线视频你懂得一区二区三区| 亚洲欧美在线一区二区| 欧美国产综合在线| 狠狠色综合欧美激情| 欧美日韩国产精品自在自线| 一区二区三区免费在线视频| www.亚洲一二| 亚洲成熟丰满熟妇高潮xxxxx| 精品高清久久| av在线日韩国产精品| 在线观看一区视频| 成人综合视频在线| 三级黄色录像视频| 亚洲精品成人无码熟妇在线| 亚洲欧美大片| 97人人澡人人爽| 午夜精品在线看| 亚洲在线色站| av电影中文字幕| 日韩精品视频一区二区三区| www日韩在线观看| 怡红院av久久久久久久| 91看片淫黄大片一级在线观看| 午夜国产在线| 天天干,天天操,天天射| 欧美人与动牲性行为| 午夜视频在线免费播放| 日本国产精品视频| 69久久夜色精品国产69| 欧美一级一区二区| 搡老熟女老女人一区二区| 亚洲经典在线| 国产一区二区免费| 欧美日韩在线播| 日韩精品人妻中文字幕有码| 欧美激情欧美激情在线五月| 成年人影院在线观看| 欧美日韩另类国产亚洲欧美一级| 欧美一级日韩免费不卡| 特级西西444www高清大视频| 色婷婷久久综合中文久久蜜桃av| 成人在线电影在线观看视频| 国产福利三区| 国产日本亚洲高清| 欧美日韩中文字幕一区二区| 96av麻豆蜜桃一区二区| 久久久久在线| 免费在线你懂的| 亚洲已满18点击进入在线看片| 少妇精品无码一区二区三区| 天堂视频免费在线观看| 网站一区二区三区| 欧美五码在线| 北条麻妃在线| 色爱综合区网| 美女扒开腿免费视频| 一本色道久久综合亚洲精品高清| 欧美视频久久久| 91豆花精品一区| 强伦女教师2:伦理在线观看| 91夜夜未满十八勿入爽爽影院| 精品久久久久久国产| 日韩欧美一区二区在线| 在线观看日韩专区| 国产男男gay体育生网站| 91精品国产自产| 无码人妻aⅴ一区二区三区有奶水| 天天操天天干天天爱| 五月天激情丁香| 男人天堂2017| 男生操女生视频在线观看| 亚洲高清视频一区二区| 国产一级久久久久毛片精品| 欧美精品999| 精品一区二区三区免费站| 91麻豆精品国产91久久久久| 在线观看你懂的网站| 色播视频在线观看| 亚洲福利二区| 日本久久一区二区| 三级在线电影| 中文字幕黄色网址| 欧美77777免费视频| 一本大道久久加勒比香蕉| 麻豆精品91| 2021天堂中文幕一二区在线观| 欧美色123| 亚洲最大的免费| 男女羞羞视频网站| 欧美激情黄色片| 男人添女人下面高潮视频| www.一区二区三区| 天天曰天天操| 超碰人人人人人人| 国产妇女馒头高清泬20p多| 亚洲午夜网未来影院| 成年人性生活视频| 四虎影视成人永久免费观看视频| 青青青在线免费观看| 九一免费在线观看| 成人精品国产福利| 亚洲欧美精品| 在线免费观看一级片| 色噜噜在线网| 成人精品在线| 国产91免费看片| 只有精品亚洲|