Java Enum 類 的 values()方法 api沒有,實例是怎麼調用詳解

源文件:


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);


很清晰,事實說明一切

發佈了41 篇原創文章 · 獲贊 13 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章