Java枚举类的高级用法说明

时间:2022-08-05 04:28:58
public enum Color{
    RED, BLUE, BLACK, YELLOW, GREEN
}
Color c = Color.RED;

如上,是我们通常使用枚举类型的常用方式。

从编写方式上看,enum很像是特殊的class,实际上enum声明定义的类型就是一个类。而这些类都是类库中Enum类的子类。查看编译之后的字节码文件可以发现enum类型被单独编译成了字节码文件Color.class。

Compiled from "Color.java"
public final class Color extends java.lang.Enum<Color> {
  public static final Color RED;
  public static final Color BLUE;
  public static final Color BLACK;
  public static final Color YELLOW;
  public static final Color GREEN;
  public static Color[] values();
  public static Color valueOf(java.lang.String);
  static {};
}

由上可知:

1. enum类型是一个不可以被继承的final类。其枚举值都是Color类型的类静态常量(这也是为什么enum会大写的原因)。

2. 既然是类,所以enum类型也有构造函数,方法和域。不过enum类型与一般class有很大的不同:

(1)构造函数只会在构造枚举值的时候被调用

enum Color{
    RED(255, 0, 0), BLUE(0, 255, 0), GREEN(0, 0, 255);//注意此处必须有分号

    private Color(int r, int g, int b){
        this.r = r;
        this.g = g;
        this.b = b;
    }        

    private int r, g, b;

    public String toString(){
        return super.toString() + "(" + r + ", " + g + ", " + b + ")";
    }  
}

(2) 为了确保构造函数不会被外部调用,因此构造函数必须是private的。

(3) 所有enum类型都会继承Enum.java的方法,包括:

     a. ordinal()方法:返回枚举值在enum类中的顺序。这个顺序依据枚举值声明时的顺序而定。

    Color.RED.oridinal(); //返回结果:0

  b. compareTo()方法:

    Color.RED.compareTo(Color.BLUE); //返回结果:-1

  c. toString():返回枚举值的名称

    Color.RED.toString(); //返回结果:RED

  d. values():返回一个包含全部枚举值的数组

    Color[] colors = Color.values();

  e. valueOf():返回枚举值常量

    Color.valueOf("BLUE"); //返回结果:Color.BLUE

  d. equals() : 比较两个枚举类对象的引用。

  

public final boolean equals(Object other){
    return this == other;  
}

 注意:枚举类和枚举值的不同

 

如上,这样我们知道了枚举值带方法和变量时的原理和用法。因此enum还有一个用法是实现接口。

public enum Color implements IColor{
    RED("红色", 1), GREEN("绿色", 2), BLUE("蓝色", 3);

    private Color(String name, int value){
      this.name =  name;
      this.value = value;
    }

    private String name;
    private int value;

    @Override
    public String getName(){
        return this.name;
    }

    @Override
    public int getValue(){
        return this.value;
    }
}

需要注意的是,哪些方法是给枚举类调用的,哪些方法是给枚举值调用的。