是枚举?还是常量?其实很好选择!

一、什么是枚举?

首先,枚举是一种特殊的类对象,其定义如下:

{修饰符} enum 对象标识 [父接口] 枚举体

枚举类型通过一些特殊的约束,来实现其应用特性:

1、枚举不可定义为abstract 或者 final,否则会引发编译器错误。

2、枚举实现了Comparable及Serializable接口,因此可以进行比较及序列化等操作,类型定义如下:

3、枚举类型只能通过内部的枚举常量进行初始化

4、枚举类型clone方法定义为final,即不可复制,否则会抛出异常:

5、枚举类型无法通过反射机制进行初始化。

6、枚举类型需要自定义处理序列化,反序列化,默认的序列化使用会抛出异常。

7、枚举类型equals定义为final,不可自定义覆盖,同关联hashCode方法。

8、枚举类型finalize定义为final,意味着枚举实例可能永远不会被垃圾回收。

二、枚举的初始化

如下图,我们定义EnvEnum类型枚举,然后通过PROD、RELEASE、DEV枚举常量初始化了三个EnvEnum实例:

枚举常量体可以包含参数,参数会通过构造函数进行枚举类型的初始化。

枚举体相当于定义了一个内部匿名类,但是不可包含构造函数及abstract方法。

枚举类型的构造函数有以下特殊约定限制:

1、构造函数默认为private修饰(不可外部初始化构造),不可使用public 或者 protected修饰,否则会导致编译错误。

2、不可在构造函数内调用父类构造函数。

3、枚举类型会默认声明无参构造函数。

三、枚举的一些特性

1、valueOf:根据枚举常量名称查找枚举实例。

枚举类型提供根据名称查询实例方法,需要注意的是,如果查找不到匹配的实例,则会抛出异常。

2、compareTo:提供枚举实例对比方法

对比需要再同类型枚举实例间,根据枚举实例的ordinal对比实现。 

四、关于使用枚举、常量

其实,很多情况下,枚举和常量可以替代使用,对于第二部分 EnvEnum 示例,我们可以定义常量类如下:

但是,在实际应用中,在不同情景下的使用便捷性及代码复杂度上,却有着不小的区别:

1、对比、查找

当需要做同类型对比,查找类操作时,常量类需要对相应的常量组定义,实现相应的功能方法。

可预知的是在实际应用中,会有很多不同类型组常量应用需求,那么各组变量的对比,查找则需要分别去实现,而枚举相应的功能囊括在枚举类型定义中,可以直接使用。

2、关联性的使用

本篇中,我们定义了不同环境的(appId、appPort)配置使用,即,在使用PROD环境配置的appId时,同时可能会使用其appPort。在不同应用情景中,可能存在更多特性配置的关联使用,这就很可能造成使用中的关联性、匹配性的麻烦和混乱。比如,不小心组合使用了PROD_APP_ID和RELEASE_APP_PORT两个变量。

枚举实例将所有的关联特性包装在一起,更适合此种情景应用,如:(EnvEnum.PROD.getAppId()、EnvEnum.PROD.getAppPort())

总的来说,常量更适用于单一或者单一组合的全局性应用,而枚举更适合多组合多属性关联的复杂情景应用。

当然,我们这里只是说适合,不是必需。

五、附加订阅

 

posted @ 2020-05-30 18:39  WindWant  阅读(5287)  评论(1编辑  收藏  举报
文章精选列表