1. 程式人生 > 實用技巧 >Java Enum 列舉類

Java Enum 列舉類

網上很多技術,都沒有以一種讓人理解的方式講解。今天讓一下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     public
static 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)就報錯,顯然,就是類似於語法的東西,會被編譯器改寫。