日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java魔法堂:枚举类型详解

發(fā)布時間:2025/7/14 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java魔法堂:枚举类型详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、前言                                

? Java的枚舉類型相對C#來說具有更靈活可配置性,Java的枚舉類型可以攜帶更多的信息。

// C# enum MyColor{RED = 0,BLUE = 1 } Console.Write(MyColor.RED);// Java enum MyColor{RED("Hot", 4), BLUE("SAD",8);private String mood;public String getMood{return mood;}private int index;public int getIndex(){return index;}private MyColor(String mood, int index){this.mood = mood;this.index = index;} } System.out.println(MyColor.RED.getMood());

? 本文將對枚舉類型進行較為詳細的敘述,以便日后查閱。

?

二、最簡單的用法——常量                        



/* 定義 */ // 形式1 enum MyColor{RED,BLUE }// 形式2 enum MyColor{RED,BLUE; } /* 使用 */ System.out.println(MyColor.RED.name()); // 顯示RED System.out.println(MyColor.RED.ordinal()); // 顯示0 System.out.println(MyColor.BLUE.name()); // 顯示BLUE System.out.println(MyColor.BLUE.ordinal()); // 顯示1
? 枚舉值的name()會返回枚舉值的字面量,而ordinal()為返回枚舉值的索引,而索引是以枚舉值定義時的位置來確定,并在編譯時設(shè)置的。下面我們來看看到底編譯器為我們做了什么?
final class MyColor extends java.lang.Enum<MyCorlor>{public static final MyColor RED;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUMpublic static final MyColor BLUE;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUMpublic static MyColor[] values();flags: ACC_PUBLIC, ACC_STATICCode:stack=1, locals=0, args_size=00: getstatic #1 // Field $VALUES:[LMyColor;3: invokevirtual #2 // Method "[LMyColor;".clone:()Ljava/lang/Object;6: checkcast #3 // class "[LMyColor;"9: areturn LineNumberTable:line 1: 0public static MyClass valueOf(java.lang.String);flags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: ldc_w #4 // class MyColor3: aload_0 4: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;7: checkcast #4 // class MyColor10: areturn LineNumberTable:line 1: 0static {};flags: ACC_STATICCode:stack=4, locals=0, args_size=00: new #4 // class MyColor3: dup 4: ldc #7 // String RED6: iconst_0 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V10: putstatic #9 // Field RED:LMyColor;13: new #4 // class MyColor16: dup 17: ldc #10 // String BLUE19: iconst_1 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V23: putstatic #11 // Field BLUE:LMyColor;26: iconst_2 27: anewarray #4 // class MyColor30: dup 31: iconst_0 32: getstatic #9 // Field RED:LMyColor;35: aastore 36: dup 37: iconst_1 38: getstatic #11 // Field BLUE:LMyColor;41: aastore 42: putstatic #1 // Field $VALUES:[LMyColor;45: return LineNumberTable:line 2: 0line 1: 26 }

?可以看到編譯器將enum MyColor編譯為一個繼承Enum<MyColor>并且?guī)揎椃鹒inal的MyColor類。

?而枚舉值RED和BLUE則被編譯為MyColor的類常量,并且在類加載的初始化階段實例化。MyColor默認的構(gòu)造函數(shù)會調(diào)用父類 Enum<MyColor>的構(gòu)造函數(shù)Enum<E>(String name, int ordinal)來設(shè)置私有字段name和ordinal的值。其中iconst_0和iconst_1分別表示將0和1壓 棧,invokespecial #8則是調(diào)用構(gòu)造函數(shù)Enum<E>(String name, int ordinal)。

0: new #4 // class MyColor3: dup 4: ldc #7 // String RED6: iconst_0 // int 07: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V10: putstatic #9 // Field RED:LMyColor;13: new #4 // class MyColor16: dup 17: ldc #10 // String BLUE19: iconst_1 // int 120: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V23: putstatic #11 // Field BLUE:LMyColor;? 另外在類加載的初始化階段會生成一個私有的$VALUE數(shù)組用于存放常量RED和BLUE,而在調(diào)用MyColor.values()返回的正是這個$VALUE數(shù)組的復(fù)制品。
26: iconst_2 27: anewarray #4 // class MyColor30: dup 31: iconst_0 32: getstatic #9 // Field RED:LMyColor;35: aastore 36: dup 37: iconst_1 38: getstatic #11 // Field BLUE:LMyColor;41: aastore 42: putstatic #1 // Field $VALUES:[LMyColor;

? 小結(jié):

? ? ?1. 定義枚舉類型本質(zhì)上就是在定義帶final修飾符的Enum<E>的子類;

? ? ?2. 枚舉值本質(zhì)為第1點所定義的類的類常量;

? ? ?3. 枚舉值的ordinal值由其定義時的排序決定,并且在編譯時已經(jīng)被設(shè)置好了。

?

三、枚舉類型的抽象父類Enum<E>                   ?

? 其實我們大多數(shù)情況下都是調(diào)用父類Enum<E>的方法來操作自定義的枚舉值,下面一起看看父類Enum<E>吧!

? 1. 它為抽象類且繼承了Comparable<E>和Serializable兩個類。

? 2. 內(nèi)含私有字段name和ordinal和對應(yīng)的公有g(shù)et方法name()和ordinal()。

? 3. 重寫了equals方法,通過==比較兩個枚舉值的內(nèi)存地址來判斷兩者是否相同。

? 4. 實現(xiàn)compareTo方法,通過比較兩個枚舉值的ordinal值來做判斷。

? 5.?getDeclaringClass方法,用于返回枚舉的Class對象。

?

四、攜帶更多信息——自定義構(gòu)造函數(shù)                   

? 由于枚舉最終被編譯為類,因此我們通過自定義構(gòu)造函數(shù)、自定義字段和方法來讓枚舉值攜帶更多信息

public enum MyColor{RED("Hot", 2), BLUE("SAD",5);private String mood;private int index;private MyColor(String mood, int index){this.mood = mood;this.index = index;} }

? 注意:

? ? 1. 自定義的構(gòu)造函數(shù)必須是私有的;

? ? 2. 構(gòu)造函數(shù)內(nèi)不能顯式調(diào)用父類的構(gòu)造函數(shù);

? ? 3. RED、BLUE的ordinal值依然是0和1,那么值依然是RED和BLUE。

?上述3點規(guī)定和結(jié)果的原因是編譯器會對我們的自定義構(gòu)造函數(shù)進行加工變?yōu)?br />

private MyColor(String name, String ordinal, String mood, int index){super(name, ordinal);this.mood = mood;this.index = index; } 五、讓相同枚舉類型下的枚舉值具有不同的行為——重寫枚舉值的方法    



public enum MyColor{RED, BLUE(){@Overridepublic boolean getFlag(){return false;}};public boolean getFlag(){return true;} } // 調(diào)用 System.out.println(MyColor.RED.getFlag()); // 顯示true System.out.println(MyColor.BLUE.getFlag()); // 顯示false

? 可以看到枚舉值RED和BLUE同一個方法具有不同的行為。其實這是通過匿名內(nèi)部類的方式實現(xiàn)的,BLUE的類型為MyColor$1 extends MyColor,而RED的類型為MyColor。

?

六、使用接口組織枚舉                          


public interface Food {enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO}enum Dessert implements Food {FRUIT, CAKE, GELATO}}

七、總結(jié)                                

? 若有紕漏請大家指正,謝謝。


總結(jié)

以上是生活随笔為你收集整理的Java魔法堂:枚举类型详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。