Java Enum 列舉類
阿新 • • 發佈:2020-07-24
網上很多技術,都沒有以一種讓人理解的方式講解。今天讓一下Java Enum 列舉類
最簡單的列舉類定義如下:
Test.java
1 enum Weekday { 2 MON, TUE, WED, THU, FRI, SAT, SUN; 3 }
這是個用於表示一週的列舉類,說到它是個 class類,卻讓人感覺怪怪的。當 java原始碼在編譯的時候,會先被改寫,然後再生成 .class檔案。所以,反編譯 .class檔案就能得到它被改寫後的程式碼。
演示過程 Test.java---> Weekday.class --->Weekday.java
PS D:\demo> ls
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2020/7/24 17:02 466 Test.java PS D:\demo> javac -encoding utf8 Test.java PS D:\demo> ls
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 2020/7/24 17:02 466 Test.java -a--- 2020/7/24 17:07 1370 Weekday.class PS D:\demo> jad -s java -o Weekday.class Parsing Weekday.class... Generating Weekday.java PS D:\demo>
Weekday.java整理如下:
1 final class Weekday extends Enum { 2 3 private Weekday(String s, int i){ 4 super(s, i); 5 } 6 7 public static final Weekday MON; 8 public static final Weekday TUE; 9 publicstatic final Weekday WED; 10 public static final Weekday THU; 11 public static final Weekday FRI; 12 public static final Weekday SAT; 13 public static final Weekday SUN; 14 private static final Weekday $VALUES[]; 15 16 static { 17 MON = new Weekday("MON", 0); 18 TUE = new Weekday("TUE", 1); 19 WED = new Weekday("WED", 2); 20 THU = new Weekday("THU", 3); 21 FRI = new Weekday("FRI", 4); 22 SAT = new Weekday("SAT", 5); 23 SUN = new Weekday("SUN", 6); 24 25 $VALUES = (new Weekday[] { 26 MON, TUE, WED, THU, FRI, SAT, SUN 27 }); 28 } 29 30 public static Weekday[] values(){ 31 32 return (Weekday[])$VALUES.clone(); 33 } 34 35 public static Weekday valueOf(String s){ 36 37 return (Weekday)Enum.valueOf(Weekday, s); 38 } 39 40 }
查得Enum類構造方法就兩個引數,名稱和索引:
1 protected Enum(String name, int ordinal) { 2 this.name = name; 3 this.ordinal = ordinal; 4 }
再看一個重寫了構造方法的列舉類:
1 enum Weekday { 2 3 MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日"); 4 5 public final int number; //數字表星期 6 private final String chinese; //中文名 7 8 private Weekday(int number, String chinese) { 9 10 this.number = number; 11 this.chinese = chinese; 12 } 13 14 @Override 15 public String toString() { 16 return this.chinese; 17 } 18 19 }
反編譯後的程式碼如下:
1 final class Weekday extends Enum { 2 3 public static final Weekday MON; 4 public static final Weekday TUE; 5 public static final Weekday WED; 6 public static final Weekday THU; 7 public static final Weekday FRI; 8 public static final Weekday SAT; 9 public static final Weekday SUN; 10 private static final Weekday $VALUES[]; 11 12 public final int number; 13 private final String chinese; 14 15 static { 16 MON = new Weekday("MON", 0, 1, "\u661F\u671F\u4E00"); 17 TUE = new Weekday("TUE", 1, 2, "\u661F\u671F\u4E8C"); 18 WED = new Weekday("WED", 2, 3, "\u661F\u671F\u4E09"); 19 THU = new Weekday("THU", 3, 4, "\u661F\u671F\u56DB"); 20 FRI = new Weekday("FRI", 4, 5, "\u661F\u671F\u4E94"); 21 SAT = new Weekday("SAT", 5, 6, "\u661F\u671F\u516D"); 22 SUN = new Weekday("SUN", 6, 0, "\u661F\u671F\u65E5"); 23 $VALUES = (new Weekday[] { MON, TUE, WED, THU, FRI, SAT, SUN }); 24 } 25 26 private Weekday(String s, int i, int j, String s1){ 27 28 super(s, i); 29 number = j; 30 chinese = s1; 31 } 32 33 public static Weekday[] values(){ 34 35 return (Weekday[])$VALUES.clone(); 36 } 37 38 public static Weekday valueOf(String s){ 39 40 return (Weekday)Enum.valueOf(Weekday, s); 41 } 42 43 public String toString(){ 44 return chinese; 45 } 46 47 }
在 Weekday類的構造方法的引數列表中,追加兩個引數。然後,內部依然呼叫父類的構造方法 Enum(String name, int ordinal)。
然後就是使用了。通常是和switch語句一起使用。
1 class Main { 2 3 public static void main(String[] args) { 4 5 Weekday day = Weekday.SUN; 6 7 switch(day){ 8 9 case MON: 10 case TUE: 11 case WED: 12 case THU: 13 case FRI: 14 System.out.println("Today is " + day + ". Work at office!"); 15 break; 16 case SAT: 17 case SUN: 18 System.out.println("Today is " + day + ". Work at home!"); 19 break; 20 default: 21 throw new RuntimeException("cannot process " + day); 22 } 23 24 } 25 }
用法很簡單,但是不免迷惑,為什麼 MON、TUE 、WED 可以直接用,當你用System.out.print(MON)就報錯,顯然,就是類似於語法的東西,會被編譯器改寫。