更新時間:2021-01-28 來源:Enum枚舉類型 瀏覽量:
Enum的全寫是Enumeration,這個詞的翻譯是列舉、逐條陳述、細(xì)目。在程序語言中,枚舉類型是一種特殊的數(shù)據(jù)類型(常用的數(shù)據(jù)類型比如字符串、整型),這種數(shù)據(jù)類型的變量值限定在固定的范圍, 比如季節(jié)只有春夏秋冬,月份是12個。
在Java語言中, 枚舉類型從JDK1.5才開始提供。在這之前使用接口靜態(tài)常量來實現(xiàn)相關(guān)功能(也可以是類靜態(tài)常量),以季節(jié)為例:
在不使用枚舉類之前,一般使用接口靜態(tài)常量實現(xiàn)。比如:
public interface Season {
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
}
使用JUnit使用測試如下:
@Test
public void noEnum() {
int i = 1;
Assert.assertTrue(Season.SPRING==i);
}
使用接口靜態(tài)常量的方式比較難限定變量的范圍,而且定義繁瑣,功能也很有限,于是在Java 1.5 中定義了一個枚舉類型:java.lang.Enum
。
類似類(class)和接口(interface)的定義,Java提供enum關(guān)鍵字用來定義枚舉類,在IDEA中創(chuàng)建枚舉類的菜單如下:
<img src="Java枚舉(Enum)類型的基本介紹與原理探求.assets/image-20200924184946393.png" alt="image-20200924184946393" style="zoom:50%;" />
同樣定義一個季節(jié)的枚舉類, 代碼可以簡潔如下:
package cn.osxm.jcodef.func.base;
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN, WINTER
}
在枚舉類中直接列出常量,常量遵循全部大寫的規(guī)則。在上面的枚舉類示例代碼中,SPRING, SUMMER, AUTUMN, WINTER 是SeasonEnum的成員。
在JUnit使用測試如下:
@Test
public void enumBase() {
SeasonEnum season = SeasonEnum.SPRING;
Assert.assertTrue(season.equals(SeasonEnum.SPRING));
}
Java枚舉類的特性有:
但是從上面SeasonEnum枚舉類的定義來看,完全看不出這些特性,這些特性是怎么來的呢? 請看下面的原理探求。
ava枚舉類型的奧秘就在編譯階段,枚舉類在編譯后會生成了一個擴(kuò)展java.lang.Enum的類。這個可以通過JDK自帶的javap工具來反編譯生成的.class文件。對上面的生成的SeasonEnum.class文件進(jìn)行反編譯,因為這個文件的包路徑是cn\osxm\jcodef\func\base,所以在命令行使用如下命令:
javap -p cn\osxm\jcodef\func\base\SeasonEnum.class
-p
參數(shù)的意思是反編譯代碼中包含私有的方法, p是private的意思。<img src="Java枚舉(Enum)類型的基本介紹與原理探求.assets/image-20200924185250968.png" alt="image-20200924185250968" style="zoom:50%;" />
從控制臺輸出的反編譯后的源碼可以看出:
java.lang.Enum
類注意: 使用專門的Java反編譯工具,比如JD GUI、luyten等對Eumn進(jìn)行反編譯的效果接近源碼的效果,無法看到繼承等特性,JD-GUI反編譯的效果和源碼時一致的,這也說明使用JD GUI來進(jìn)行實際的反編譯還是不錯的。