【原理】
寫一個枚舉,相信大家都會,如:
1public enum City {Guangzhou, Shenzhen, Dongguan}
這是個城市的枚舉類,包含廣州、深圳、東莞三個城市枚舉值,但是它怎麼用呢?它的背後的真面目是怎樣的呢?
下面我們來反編譯一下這個枚舉,結果得出:
1public final class City extends Enum<City> {
2 public static final City[] values() {
3 return (City[]) $VALUES.clone();
4 }
5 public static City valueOf(String name) {
6 return (City) Enum.valueOf(City, name);
7 }
8 // 構造函數
9 private City(String s, int i) {
10 super();
11 }
12 public static final City Guangzhou;
13 public static final City Shenzhen;
14 public static final City Dongguan;
15
16 private static final City $VALUES[];
17 // 實例化枚舉
18 static {
19 Guangzhou = new City("Guangzhou", 0);
20 Shenzhen = new City("Shenzhen", 1);
21 Dongguan = new City("Dongguan", 2);
22 $VALUES = (new City[] { Guangzhou, Shenzhen, Dongguan });
23 }
24}
從這個類中我們可以看出幾點:
1)是個類 並且是final類,繼承與java.lang.Enum類 不可繼承。
2)用static塊初始化。
3)定義了幾個final類型的City對象,並且在static塊中初始化。
由此可以知道,enum本質是一個final類,而JavaAPI的設計出的這個Enum,是一個被封裝之後的類,旨在提供一種代碼簡潔而高效的類型管理組件,簡化開發者編碼。這當然是廢話啦,各位看看,同樣是功能的兩種寫法哪一種更簡潔?哪一種更值得用?
我們再來看看enum接口類的源碼:
1public abstract class Enum<E extends Enum<E>>
2 implements Comparable<E>, Serializable {
3 //枚舉常量名稱
4 private final String name;
5 //返回枚舉常量名稱
6 public final String name() {
7 return name;
8 }
9 //枚舉常量的序數 初始值爲0 根據位置而得出
10 private final int ordinal;
11// 返回枚舉常量的序數
12 public final int ordinal() {
13 return ordinal;
14 }
15 //私有構造函數,程序無法直接調用改函數進行初始化
16 //它用於由響應枚舉類型聲明的編譯器發出的代碼
17 //@param name:枚舉常量的名稱
18 //@param ordinal: 枚舉常量的序數
19 protected Enum(String name, int ordinal) {
20 this.name = name;
21 this.ordinal = ordinal;
22 }
23 //和name()是一個意思
24 public String toString() {
25 return name;
26 }
27 //判斷是否相同對象的函數
28 public final boolean equals(Object other) {
29 return this==other;
30 }
31 //爲枚舉返回一個hashCode
32 public final int hashCode() {
33 return super.hashCode();
34 }
35 //克隆函數
36 protected final Object clone() throws CloneNotSupportedException {
37 throw new CloneNotSupportedException();
38 }
39 //比較此枚舉與指定對象的順序(編號)。
40 //在該對象小於、等於或大於指定對象時,分別返回負整數、零或正整數。
41 //枚舉常量只能與相同枚舉類型的其他枚舉常量進行比較。
42 //該方法實現的自然順序就是聲明常量的順序。
43 public final int compareTo(E o) {
44 Enum<?> other = (Enum<?>)o;
45 Enum<E> self = this;
46 if (self.getClass() != other.getClass() && // optimization
47 self.getDeclaringClass() != other.getDeclaringClass())
48 throw new ClassCastException();
49 return self.ordinal - other.ordinal;
50 }
51// 以下方法略過....
52}
有了這個抽象類Enum的源碼,我們基本上知道枚舉是怎麼使用的了,下面是一些常用的方法:
方法名 |
返回值 |
說明 |
name() |
String |
返回枚舉的名稱 |
ordinal() |
int |
返回枚舉常量的序數 |
compareTo(E o) |
int |
比較此枚舉與指定對象的順序(編號)。 在該對象小於、等於或大於指定對象時,分別返回負整數、零或正整數。 枚舉常量只能與相同枚舉類型的其他枚舉常量進行比較。 該方法實現的自然順序就是聲明常量的順序 |
【使用方式】
Enum類實現三種枚舉:
1)最常用:
1public enum Num {
2 ONE,TWO,THREE;
3}
2)定義帶參構造函數:
1public enum EnumTest{
2 ONE("1","YI");
3 private String name;
4 private String value;
5 //一個參
6 private EnumTest(String name){
7 this.name=name;
8 }
9 //兩個參數
10 private EnumTest(String name,String value){
11 this.name=name;
12 this.value=value;
13 }
14 //...多個參數
15 public static void main(String[] args) {
16 System.out.println(EnumTest.ONE.name);
17 System.out.println(EnumTest.ONE.value);
18 }
19}
3)抽象方法實現:
1public enum EnumTest{
2 ONE("1") {
3 @Override
4 public void handle() {
5 // TODO Auto-generated method stub
6 }
7 };
8 private String name;
9 private EnumTest(String name){
10 this.name=name;
11 }
12 //定義抽象方法
13 public abstract void handle();
14 public static void main(String[] args) {
15 //調用
16 EnumTest.ONE.handle();
17 }
18}
【注意事項】
1)不能繼承,因爲枚舉類本身已經繼承了Enum抽象類,而Java是單繼承
2)枚舉的第一行必須是枚舉項,所有其它的變量和方法都必須在枚舉項後面
3) 枚舉類可以定義抽象方法,但沒枚舉項必須重寫所有抽象方法
4)可以在switch中使用枚舉,它的使用方法如下:
1switch(EnumTest.ONE){
2
3case ONE:
4
5break;
6
7case TWO:
8
9break;
10
11}
覺得本文對你有幫助?請分享給更多人
關注「編程無界」,提升裝逼技能