Java16:枚举类型

使用enum来定义枚举类:

enum Weekday {
    SUN, MON, TUE, WED, THU, FRI, SAT; //依次列出枚举的常量名
}

class test {
    public static void main(String[] args) {
        Weekday day = Weekday.SUN;  //为枚举类型
        if (day == Weekday.SUN) { }
    }
}

使用enum定义的枚举类是一种引用类型。通常情况下,引用类型进行比较要使用equals()方法,如果使用==比较,它比较的是两个引用类型的变量是否是同一个对象。
但enum类型可以例外,因为enum类型的每个常量在JVM中只有一个唯一实例,所以可以直接用==比较

enum定义的类型本质上就是class,它的独特之处是:

  • 定义的enum类型总是继承自java.lang.Enum,且无法被继承
  • 只能定义出enum的实例,而无法通过new操作符创建enum的实例
  • 定义的每个实例都是引用类型的唯一实例
  • 可以将enum类型用于switch语句
    枚举类天生具有类型信息和有限个枚举常量,非常适合用于switch语句

例如,定义的Color枚举类:

public enum Color {
    RED, GREEN, BLUE;
}

编译器编译出的class大概就像这样:

public final class Color extends Enum { // 继承自Enum,标记为final class

    public static final Color RED = new Color();  // 枚举变量其实是一个实例
    public static final Color GREEN = new Color(); // 每个实例均为全局唯一:
    public static final Color BLUE = new Color();

    private Color() {} // private构造方法,确保外部无法调用new操作符
    ...
}

枚举类的创建本质:

enum {
	//SUN, MON, TUE, WED, THU, FRI, SAT;
	//SUN(3), MON(1), TUE(4), WED(0), THU(2), FRI(5), SAT(6);
	//MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");
	//本质上是调用构造函数创建了一个实例对象
}
简写 实际核心代码
SUN Weekday SUN = new Weekday()
SUN(3) Weekday SUN = new Weekday(3)
SUN(3, "星期日") Weekday SUN = new Weekday(3, "星期日")

因此也可以自己给enum编写构造方法、变量和方法。
(enum的构造方法要声明为private,变量强烈建议声明为final)


enum类中还有一些实例函数:

  • name():将枚举量转换为字符串,返回字符串
String s = Weekday.SUN.name(); // "SUN"
  • ordinal():返回定义的常量的顺序(即转为int型),默认从0开始计数
int n = Weekday.MON.ordinal(); // 1

如果想要指定每个枚举常量对应的int型数字,可以自定义构造函数为:

enum Weekday {
    SUN(3), MON(1), TUE(4), WED(0), THU(2), FRI(5), SAT(6);

    public final int value;

    private Weekday(int value) {
        this.value = value;
    }
}

class test {
    public static void main(String[] args) {
        Weekday day = Weekday.SUN;
        System.out.println(day.value);
    }
}

如此即使枚举常量的顺序改变,其对应的int值仍不会变,提高了代码的健壮性。

  • toString():默认情况下,对枚举常量调用toString()会和name()一样返回相同的字符串。但是,toString()可以被重写,而name()则不行
class test {
    public static void main(String[] args) {
        Weekday day = Weekday.SUN;
        System.out.println(day.name());  //SUN
        System.out.println(day.toString()); //星期日
        System.out.println("Today is " + day); //Today is 星期日
        //引用类型转化为字符串时,会自动调用toString()方法
    }
}

enum Weekday {
    MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");

    public final int dayValue;
    private final String chinese;

    private Weekday(int dayValue, String chinese) { //构造函数
        this.dayValue = dayValue;
        this.chinese = chinese;
    }

    @Override
    public String toString() {  //重写toString函数
        return this.chinese;
    }
}

重写toString()的目的是在输出时更有可读性。
注意:判断枚举常量的名字时,要始终使用name()方法,绝不能调用toString()!

上一篇:Https 协议,报错:javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake


下一篇:Python subprocess模块