Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 public, static、final 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。
【1】自定义常量实现类似枚举类
实例如下:
//枚举类
class Season{
  //1.提供类的属性,声明为private final 
  private final String seasonName;
  private final String seasonDesc;
  
//2.声明为final而没有用static修饰的属性,要么在定义的时候初始化,要么在构造器中初始化。
  private Season(String seasonName,String seasonDesc){
    this.seasonName = seasonName;
    this.seasonDesc = seasonDesc;
  }
  
  //3.通过公共的方法来调用属性
  public String getSeasonName() {
    return seasonName;
  }
  public String getSeasonDesc() {
    return seasonDesc;
  }
//4.创建枚举类的对象:将类的对象声明public static final,每个常量都是一个Season实例对象;
  public static final Season SPRING = new Season("spring", "春暖花开");
  public static final Season SUMMER = new Season("summer", "夏日炎炎");
  public static final Season AUTUMN = new Season("autumn", "秋高气爽");
  public static final Season WINTER = new Season("winter", "白雪皑皑");
  
  @Override
  public String toString() {
    return "Season [seasonName=" + seasonName + ", seasonDesc="
        + seasonDesc + "]";
  }
  //5.声明一个公共方法
  public void show(){
    System.out.println("这是一个季节");
  }
}测试方法如下:
public static void main(String[] args) {
  Season spring = Season.SPRING;
  System.out.println(spring);
  spring.show();
  System.out.println(spring.getSeasonName());
}
【2】使用enum关键字
① 使用enum关键字自定义枚举类
使用enum关键字的类都是枚举类public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {}的子类。
该类的属性和方法如下所示:
name为枚举类常量的名字,oridinal为枚举类常量的索引/序列号/position,从 0 开始。
自定义MyEnum 实例如下:
public  enum  MyEnum {
  spring,summer,autumn,winter;
  
  @Override
  public String toString() {
    // TODO Auto-generated method stub
    return "name : "+super.toString()+" , oridinal : "+super.ordinal();
  }
}测试类如下:
@Test
public void TestEnum(){
  //第一种获取方式
  MyEnum spring = MyEnum.spring;
  System.out.println(spring.toString());
  
  //第二种获取方式
  MyEnum summer = MyEnum.valueOf("summer");
  System.out.println(summer.toString());
  
  //第三种获取方式
  MyEnum autumn = MyEnum.valueOf(MyEnum.class, "autumn");
  System.out.println(autumn.toString());
  System.out.println("**********************");
  
  //遍历所有枚举常量
  MyEnum[] values = MyEnum.values();
  for(int i = 0;i < values.length;i++){
    System.out.println(values[i]);
  }
}测试结果如下:
name : spring , oridinal : 0
name : summer , oridinal : 1
name : autumn , oridinal : 2
**********************
name : spring , oridinal : 0
name : summer , oridinal : 1
name : autumn , oridinal : 2② 修改【1】中实例使用values/valueOf方法并继承接口
修改【1】中实例如下:
//接口,让枚举类继承
interface Info{
  void show();
}
//枚举类---因为是内部类,在一个java文件中,所以没有public
enum Season1 implements Info{
  SPRING("spring", "春暖花开"){
    public void show(){
      System.out.println("春天在哪里?");
    }
  },//注意这里是逗号 “,”
  SUMMER("summer", "夏日炎炎"){
    public void show(){
      System.out.println("生如夏花");
    }
  },
  AUTUMN("autumn", "秋高气爽"){
    public void show(){
      System.out.println("秋天是用来分手的季节");
    }
  },
  WINTER("winter", "白雪皑皑"){
    public void show(){
      System.out.println("冬天里的一把火");
    }
  };
  //枚举的属性
  private final String seasonName;
  private final String seasonDesc;
  
  //构造器
  private Season1(String seasonName,String seasonDesc){
    this.seasonName = seasonName;
    this.seasonDesc = seasonDesc;
  }
  public String getSeasonName() {
    return seasonName;
  }
  public String getSeasonDesc() {
    return seasonDesc;
  }
  
  @Override
  public String toString() {
    return "Season [seasonName=" + seasonName + ", seasonDesc="+ seasonDesc + "]";
  }
}测试方法修改如下:
public static void main(String[] args) {
  Season1 spring = Season1.SPRING;
  System.out.println(spring);
  spring.show();
  System.out.println(spring.getSeasonName());
  
  System.out.println();
  //1.values() 使用values方法获取其所有枚举值然后遍历输出
  Season1[] seasons = Season1.values();
  for(int i = 0;i < seasons.length;i++){
    System.out.println(seasons[i]);
  }
  //2.valueOf(String name):要求传入的形参name是枚举类对象的名字。
  //否则,报java.lang.IllegalArgumentException异常
  String str = "WINTER";
  Season1 sea = Season1.valueOf(str);
  System.out.println("****"+sea);
  System.out.println();
  sea.show();
  
  //遍历打印线程状态枚举值
  Thread.State[] states = Thread.State.values();
  for(int i = 0;i < states.length;i++){
    System.out.println(states[i]+","+states.toString()+","+states.length);
  }
  
}
【3】枚举类比较
如下所示,Java中常见的值比较和地址比较:
| 类别 | 值比较 | 地址比较 | 
| 简单类型 | == | |
| 包装类型 | equals | == | 
| 引用类型 | equals | == | 
那么枚举类呢?
枚举类是不能通过new 构造函数来创建对象的,只能通过类似于XxxEnum.SPRING来获取枚举实例。可以理解为枚举类的实例是已经预定义且被实例化好的几个有限的对象。
故而,如下所示x和y是指向同一实例对象的,二者==和equals效果相同。
GameEnum x = GameEnum.BIG;
GameEnum y = GameEnum.BIG;再来看一下ENUM类的equals方法源码:
public final boolean equals(Object other) {
        return this==other;
    }直接使用了==比较!!!
总结:enum进行比较==和equals效果相同。
【4】枚举类在定义返回结果中的应用
通常会定义一些状态码与对应的描述信息作为系统返回结果使用,这里使用枚举类实例如下:
public enum  StatusCodeEnum {
    ENUM_NOT_5GSA("000100","非5GSA用户!");
    ENUM_NOT_USER("000101","用户不存在!");
    private String code;
    private String message;
    StatusCodeEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }
    StatusCodeEnum() {
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public String toString() {
        return "StatusCodeEnum{" +
                "code='" + code + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}                
                










