Java Enum 类 的 values()方法 api没有,实例是怎么调用详解

时间:2021-11-15 04:41:05

源文件:


1
2
3
4
5
package test;
 
public enum EnumTest {
     A, B, C
}

可以看看它的字节码(javap -v EnumTest.class > EnumTest.bytecode):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
public final class test.EnumTest extends java.lang.Enum<test.EnumTest>
   SourceFile: "EnumTest.java"
   Signature: # 49                          // Ljava/lang/Enum<Ltest/EnumTest;>;
   minor version: 0
   major version: 51
   flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
 
Constant pool:
    # 1 = Class              # 2             //  test/EnumTest
    # 2 = Utf8               test/EnumTest
    # 3 = Class              # 4             //  java/lang/Enum
    # 4 = Utf8               java/lang/Enum
    # 5 = Utf8               A
    # 6 = Utf8               Ltest/EnumTest;
    # 7 = Utf8               B
    # 8 = Utf8               C
    # 9 = Utf8               ENUM$VALUES
   # 10 = Utf8               [Ltest/EnumTest;
   # 11 = Utf8               <clinit>
   # 12 = Utf8               ()V
   # 13 = Utf8               Code
   # 14 = String             # 5             //  A
   # 15 = Methodref          # 1 .# 16         //  test/EnumTest."<init>":(Ljava/lang/String;I)V
   # 16 = NameAndType        # 17 :# 18        //  "<init>":(Ljava/lang/String;I)V
   # 17 = Utf8               <init>
   # 18 = Utf8               (Ljava/lang/String;I)V
   # 19 = Fieldref           # 1 .# 20         //  test/EnumTest.A:Ltest/EnumTest;
   # 20 = NameAndType        # 5 :# 6          //  A:Ltest/EnumTest;
   # 21 = String             # 7             //  B
   # 22 = Fieldref           # 1 .# 23         //  test/EnumTest.B:Ltest/EnumTest;
   # 23 = NameAndType        # 7 :# 6          //  B:Ltest/EnumTest;
   # 24 = String             # 8             //  C
   # 25 = Fieldref           # 1 .# 26         //  test/EnumTest.C:Ltest/EnumTest;
   # 26 = NameAndType        # 8 :# 6          //  C:Ltest/EnumTest;
   # 27 = Fieldref           # 1 .# 28         //  test/EnumTest.ENUM$VALUES:[Ltest/EnumTest;
   # 28 = NameAndType        # 9 :# 10         //  ENUM$VALUES:[Ltest/EnumTest;
   # 29 = Utf8               LineNumberTable
   # 30 = Utf8               LocalVariableTable
   # 31 = Methodref          # 3 .# 16         //  java/lang/Enum."<init>":(Ljava/lang/String;I)V
   # 32 = Utf8               this
   # 33 = Utf8               values
   # 34 = Utf8               ()[Ltest/EnumTest;
   # 35 = Methodref          # 36 .# 38        //  java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
   # 36 = Class              # 37            //  java/lang/System
   # 37 = Utf8               java/lang/System
   # 38 = NameAndType        # 39 :# 40        //  arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
   # 39 = Utf8               arraycopy
   # 40 = Utf8               (Ljava/lang/Object;ILjava/lang/Object;II)V
   # 41 = Utf8               valueOf
   # 42 = Utf8               (Ljava/lang/String;)Ltest/EnumTest;
   # 43 = Methodref          # 3 .# 44         //  java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
   # 44 = NameAndType        # 41 :# 45        //  valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
   # 45 = Utf8               (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
   # 46 = Utf8               SourceFile
   # 47 = Utf8               EnumTest.java
   # 48 = Utf8               Signature
   # 49 = Utf8               Ljava/lang/Enum<Ltest/EnumTest;>;
{
   public static final test.EnumTest A;
     flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
 
 
   public static final test.EnumTest B;
     flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
 
 
   public static final test.EnumTest C;
     flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
 
 
   static {};
     flags: ACC_STATIC
 
     Code:
       stack= 4 , locals= 0 , args_size= 0
          0 : new           # 1                  // class test/EnumTest
          3 : dup          
          4 : ldc           # 14                 // String A
          6 : iconst_0     
          7 : invokespecial # 15                 // Method "<init>":(Ljava/lang/String;I)V
         10 : putstatic     # 19                 // Field A:Ltest/EnumTest;
         13 : new           # 1                  // class test/EnumTest
         16 : dup          
         17 : ldc           # 21                 // String B
         19 : iconst_1     
         20 : invokespecial # 15                 // Method "<init>":(Ljava/lang/String;I)V
         23 : putstatic     # 22                 // Field B:Ltest/EnumTest;
         26 : new           # 1                  // class test/EnumTest
         29 : dup          
         30 : ldc           # 24                 // String C
         32 : iconst_2     
         33 : invokespecial # 15                 // Method "<init>":(Ljava/lang/String;I)V
         36 : putstatic     # 25                 // Field C:Ltest/EnumTest;
         39 : iconst_3     
         40 : anewarray     # 1                  // class test/EnumTest
         43 : dup          
         44 : iconst_0     
         45 : getstatic     # 19                 // Field A:Ltest/EnumTest;
         48 : aastore      
         49 : dup          
         50 : iconst_1     
         51 : getstatic     # 22                 // Field B:Ltest/EnumTest;
         54 : aastore      
         55 : dup          
         56 : iconst_2     
         57 : getstatic     # 25                 // Field C:Ltest/EnumTest;
         60 : aastore      
         61 : putstatic     # 27                 // Field ENUM$VALUES:[Ltest/EnumTest;
         64 : return       
       LineNumberTable:
         line 4 : 0
         line 3 : 39
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
 
   public static test.EnumTest[] values();
     flags: ACC_PUBLIC, ACC_STATIC
 
     Code:
       stack= 5 , locals= 3 , args_size= 0
          0 : getstatic     # 27                 // Field ENUM$VALUES:[Ltest/EnumTest;
          3 : dup          
          4 : astore_0     
          5 : iconst_0     
          6 : aload_0      
          7 : arraylength  
          8 : dup          
          9 : istore_1     
         10 : anewarray     # 1                  // class test/EnumTest
         13 : dup          
         14 : astore_2     
         15 : iconst_0     
         16 : iload_1      
         17 : invokestatic  # 35                 // Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
         20 : aload_2      
         21 : areturn      
       LineNumberTable:
         line 1 : 0
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
 
   public static test.EnumTest valueOf(java.lang.String);
     flags: ACC_PUBLIC, ACC_STATIC
 
     Code:
       stack= 2 , locals= 1 , args_size= 1
          0 : ldc           # 1                  // class test/EnumTest
          2 : aload_0      
          3 : invokestatic  # 43                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
          6 : checkcast     # 1                  // class test/EnumTest
          9 : areturn      
       LineNumberTable:
         line 1 : 0
       LocalVariableTable:
         Start  Length  Slot  Name   Signature
}
从字节码可以看出一下几点:
1.它是Enum的子类。


1
public final class test.EnumTest extends java.lang.Enum<test.EnumTest>

2.枚举常量是以public static final类常量的形式实现的。


1
public static final test.EnumTest A;

1
public static final test.EnumTest B;

1
public static final test.EnumTest C;
3.编译器自动生成了values和valueOf方法。 

1
public static test.EnumTest[] values();

1
public static test.EnumTest valueOf(java.lang.String);


很清晰,事实说明一切