[Java基礎知識] Java枚舉實現原理

定義

一個事物的全部值的集合。

枚舉類型的屬性 java

  由於枚舉類型所表明的是一個事物的全部值的集合,因此枚舉類型應具備的屬性爲:程序員

  1. 枚舉類型所具備的值是不可變的。
  2. 具備全部的值

枚舉的做用

限定值的範圍,一般能夠用來限制接口的參數的取值範圍。

枚舉的實現原理

  經過使用反編譯命令javap咱們能夠得出一下結論:segmentfault

  1. 編譯器將枚舉類型編譯爲final類型的class類。
  2. 枚舉中的每個枚舉值編譯爲「public static final 類型 枚舉值」的形式。
  3. 編譯器編譯以後增長了一個靜態塊,在此靜態塊中建立一個新的對象並將此對象賦值給第2點中的靜態對象。

  由以上三點確保了枚舉的特性之一:枚舉類型所具備的值是不可變的
  而枚舉的另外一個特性具備全部的值則是由程序員來實現。
使用javap -c 反編譯結果爲:code

public final class Season extends java.lang.Enum<Season> {
  public static final Season SPIRNG;

  public static final Season SUMMER;

  public static final Season AUTUMN;

  public static final Season WINTER;

  public static Season[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LSeason;
       3: invokevirtual #2                  // Method "[LSeason;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[LSeason;"
       9: areturn

  public static Season valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class Season
       2: aload_0
       3: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #4                  // class Season
       9: areturn

  static {};
    Code:
       0: new           #4                  // class Season
       3: dup
       4: ldc           #7                  // String SPIRNG
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field SPIRNG:LSeason;
      13: new           #4                  // class Season
      16: dup
      17: ldc           #10                 // String SUMMER
      19: iconst_1
      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #11                 // Field SUMMER:LSeason;
      26: new           #4                  // class Season
      29: dup
      30: ldc           #12                 // String AUTUMN
      32: iconst_2
      33: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      36: putstatic     #13                 // Field AUTUMN:LSeason;
      39: new           #4                  // class Season
      42: dup
      43: ldc           #14                 // String WINTER
      45: iconst_3
      46: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      49: putstatic     #15                 // Field WINTER:LSeason;
      52: iconst_4
      53: anewarray     #4                  // class Season
      56: dup
      57: iconst_0
      58: getstatic     #9                  // Field SPIRNG:LSeason;
      61: aastore
      62: dup
      63: iconst_1
      64: getstatic     #11                 // Field SUMMER:LSeason;
      67: aastore
      68: dup
      69: iconst_2
      70: getstatic     #13                 // Field AUTUMN:LSeason;
      73: aastore
      74: dup
      75: iconst_3
      76: getstatic     #15                 // Field WINTER:LSeason;
      79: aastore
      80: putstatic     #1                  // Field $VALUES:[LSeason;
      83: return
}

源代碼:對象

public enum Season {
    SPIRNG,
    SUMMER,
    AUTUMN,
    WINTER;
}

因爲枚舉類型使用static塊來進行初始化,因此枚舉類型僅僅在每次類加載的時候初始化,這種特性能夠用來實現單例模式參考個人另一篇文章單例模式接口

相關文章
相關標籤/搜索