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) 就报错,显然,就是类似于语法糖的东西,会被编译器改写。

 

posted @ 2020-07-24 17:58  心随所遇  阅读(239)  评论(0编辑  收藏  举报