枚举详解

 参考:https://zhuanlan.zhihu.com/p/51296740

一、枚举类型初探,定义一个Season枚举

  

public enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

测试枚举类型的name、ordinal

public class SeasonTest {
    
    @Test
    public void test() {
        System.out.println("Season Spring:"+Season.SPRING.name());
        System.out.println("Season Spring ordinal:"+Season.SPRING.ordinal());
        System.out.println("Season Summer:"+Season.SUMMER.name());
        System.out.println("Season Summer ordinal:"+Season.SUMMER.ordinal());
    }

}

输出结果:

Season Spring:SPRING
Season Spring ordinal:0
Season Summer:SUMMER
Season Summer ordinal:1

总结:Java自动给按照枚举值出现的顺序,从0开始分配了编号。通过name()可以获得枚举值的名称,通过ordinal()可以获得枚举值的编号。

二、枚举的实现原理

  Season枚举类可以调用name()、ordinal()方法,因此Season枚举类应该是继承了Enum抽象类,但是我们平常继承extends关键字继承,Season却没有。

       验证Season有没有继承Enum、或者可以不可以在继承其他类(只能单继承): 反编译下  javap Season.class

    

public final class com.converter.Season extends java.lang.Enum<com.converter.Season> {
  public static final com.converter.Season SPRING;
  public static final com.converter.Season SUMMER;
  public static final com.converter.Season AUTUMN;
  public static final com.converter.Season WINTER;
  static {};
  public static com.converter.Season[] values();
  public static com.converter.Season valueOf(java.lang.String);
}
  • 枚举类在经过编译后确实是生成了一个扩展了java.lang.Enum的类
  • 枚举类是final的,因此我们无法再继承它了
  • 成员的类型仍然是Season类型
  • 枚举类中被默认增加了许多静态方法

   为了进一步了解每个方法中的操作,我们使用javap -c Season.class每个方法中的字节码,根据字节码还原操作码:

  

public final class com.converter.Season extends java.lang.Enum<com.converter.Season> {
  public static final com.converter.Season SPRING;

  public static final com.converter.Season SUMMER;

  public static final com.converter.Season AUTUMN;

  public static final com.converter.Season WINTER;

  private static  com.converter.Season[] $VALUES;
  public static com.converter.Season[] values(){
     return (Season[])$VALUES.clone;   
}
 public static com.converter.Season  valueOf(String s){
    return (Season)Enum.valueOf(java/lang/string,s);
}
private com.converter(String s,int i){
     super(s,i);   
    }

static{
   SPRING=new Season("SPRING",0);   
   SUMMER=new Season("SUMMER",1);
  AUTUMN=new Season("AUTUMN:,2);
  WINTER=new Season("WINTER",3);
  $VALUES=(new Season[]{"SPRING","SUMMER","AUTUMN","WINTER"});
}


}

 

   

通过这里我们可以看到,在类的static操作中,编译器帮助我们生成每个枚举值的对象。

 

我们在总结一下,我们使用enum定义的枚举类型,会在编译之后转化为一个继承了java.lang.Enum的类,而我们定义的每个枚举值都会在类的初始化阶段被实例化为我们所定义的枚举类的一个对象。

 

同时,编译器还帮我们在类中增加了两个方法,分别是:values()和valueOf()。

 

 

  

posted @ 2020-04-20 16:28  StrangerIt  阅读(262)  评论(0)    收藏  举报