ENUM 枚举 使用 深度讲解 一

JAVA枚举类型(Enum)的使用

在现实社会中,有些类的实例对象是固定的。例如季节,只有春夏秋冬。例如月份,只有1-12个月,如果你创建了一个月份类,你当然有义务维护这个类的实例对象只能12个。这个时候就体现出枚举类的作用了,java中枚举类型就是针对这样的场景需求所设计的。

语法(定义)

创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。

使用MonthEnum这个枚举类的方法如下:

 

 

创建MonthEnum枚举类,在使用的时候利用switch语句进行匹配从而得到相应的输出值,这种做法很常见。如果只需要实现这样的功能,定义一个常量类也可以实现。那么就让我们更进一步来看看枚举类的作用,针对上面的例子,如果我们在很多场景下都要通过MonthEnum的实例对象获取相对应的中文,每次都使用switch语句就显得代码冗余。开发中,我们可以通过创建MonthEnum这个枚举类时,让MonthEnum中的每一个实例对象都有一个getChineseDesc()方法获取中文描述。

 

枚举类限制了此类的实例对象。当然,枚举类可以有自己的成员变量和方法。上面的MonthEnum枚举类有了chineseDesc这个成员变量,所以我们在定义实例对象时就要维护这个chineseDesc成员变量。此时调用简化代码如下:

 

 

还有另外一种方式:

 

 

就是先定义一个接口,接口中定义获取的方法。然后又枚举类生声明实现接口,并由具体枚举类对象实现方法。

示例如下:

基类接口

子实现类-枚举类

注意枚举中所有的枚举实例必须均实现接口方法。

调用方式如下:

 

我们把枚举类的所有实例对象,看做是一个集合,上面的switch可以看做是一种集合的遍历方式,当对象集size很大时,遍历很繁琐,极端不适合开发。

所以有下面的遍历方式如下:

遍历的顺序是枚举的实例对象声明的顺序。

上面的枚举对象中使用的values的方法,下面介绍枚举中的方法:

int compareTo(E o) 
          比较此枚举与指定对象的顺序。

Class<E> getDeclaringClass()

返回与此枚举常量的枚举类型相对应的 Class 对象。

String name()

返回此枚举常量的名称,在其枚举声明中对其进行声明。

int ordinal()

返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

String toString()

返回枚举常量的名称,它包含在声明中。

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

返回带指定名称的指定枚举类型的枚举常量。

 

给 enum 自定义属性和方法

EnumSet,EnumMap 的应用

 

下面讨论什么场景使用枚举类

当一个类的对象是存在且数量有限且固定的,这种情况下我们使用枚举类就比较适当。

 枚举类更加直观,类型安全。使用常量会有以下几个缺陷:

 

  1. 类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。

2. 没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。

三、枚举类的语法及声明注意事项

先看一个简单的枚举类。

1.enum和class、interface的地位一样

2.使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。

3.枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。

4.使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。

5.枚举类的构造器只能是私有的。

四.枚举类介绍

枚举类内也可以定义属性和方法,可是是静态的和非静态的。

实际上在第一行写枚举类实例的时候,默认是调用了构造器的,所以此处需要传入参数,因为没有显式申明无参构造器,只能调用有参数的构造器。

构造器需定义成私有的,这样就不能在别处申明此类的对象了。枚举类通常应该设计成不可变类,它的Field不应该被改变,这样会更安全,而且代码更加简洁。所以我们将Field用private final修饰。

 

五、枚举类实现接口

枚举类可以实现一个或多个接口。与普通类一样,实现接口的时候需要实现接口中定义的所有方法,若没有完全实现,那这个枚举类就是抽象的,只是不需显式加上abstract修饰,系统化会默认加上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章