🦔枚举类
2021-3-6
| 2023-8-3
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
如果希望定义周一到周日这7个常量,可以用7个不同的int表示:
 
也可以把常量定义为字符串类型:
 
无论是int常量还是String常量,使用这些常量来表示一组枚举值的时候,有一个严重的问题就是,编译器无法检查每个值的合理性。例如:
上述代码编译和运行均不会报错,但存在两个问题:
  • 注意到Weekday定义的常量范围是0~6,并不包含7,编译器无法检查不在枚举中的int值;
  • 定义的常量仍可与其他变量比较,但其用途并非是枚举星期值。
 

enum

为了让编译器能自动检查某个值在枚举的集合内,并且,不同用途的枚举需要不同的类型来标记,不能混用,可以使用enum来定义枚举类:
 
int定义的常量相比,使用enum定义枚举有如下好处:
  • enum常量本身带有类型信息,即Weekday.SUN类型是Weekday,编译器会自动检查出类型错误:
    • 不可能引用到非枚举的值,因为无法通过编译
    • 不同类型的枚举不能互相比较或者赋值,因为类型不符:
      这就使得编译器可以在编译期自动检查出所有可能的潜在错误。
       

      enum的比较

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

      enum类型

      通过enum定义的枚举类,和其他的class有什么区别?
      没有任何区别,enum定义的类型就是class,只不过它有以下几个特点:
      • 定义的enum类型总是继承自java.lang.Enum,且无法被继承
      • 只能定义出enum的实例,而无法通过new操作符创建enum的实例
      • 定义的每个实例都是引用类型的唯一实例
      • 可以将enum类型用于switch语句
       
      例如定义Color枚举类:
      编译器编译出的class大概就像这样:
      所以,编译后的enum类和普通class并没有任何区别。但是无法按定义普通class那样来定义enum,必须使用enum关键字,这是Java语法规定的。
       
       
      因为enum是一个class,每个枚举的值都是class实例,因此,这些实例有一些方法:

      name()

      返回常量名:

      ordinal()

      返回定义的常量的顺序,从0开始计数:
      改变枚举常量定义的顺序就会导致ordinal()返回值发生变化:
      ordinal就是不同的。如果在代码中编写了类似if(x.ordinal()==1)这样的语句,就要保证enum的枚举顺序不能变。新增的常量必须放在最后。
      Weekday的枚举常量如果要和int转换,使用ordinal()不是非常方便?比如这样写:
      但是,如果不小心修改了枚举的顺序,编译器是无法检查出这种逻辑错误的。要编写健壮的代码,就不要依靠ordinal()的返回值。因为enum本身是class,所以可以定义private的构造方法,并且,给每个枚举常量添加字段:
      这样就无需担心顺序的变化,新增枚举常量时,也需要指定一个int值。
       
      默认情况下,对枚举常量调用toString()会返回和name()一样的字符串。但是,toString()可以被覆写,而name()则不行,可以给Weekday添加toString()方法:
      覆写toString()的目的是在输出时更有可读性
       

      switch

      枚举类可以应用在switch语句中。因为枚举类天生具有类型信息和有限个枚举常量,所以比intString类型更适合用在switch语句中:
    • Java
    • JavaBean记录类
      目录