abstract
在数据交互时,常量往往和显示到页面的并不一样,如表示性别时,男(0),女(1)。代码里记 0、1 页面表示用男女。
1 | int gender = xxx; |
在类型判断的时候直接使用0
、1
来 ==
或equals
并不利于代码的强壮性。
可以有两种解决方案:
- 自定义常量类或常量接口
- 枚举类
常量类
可以用类或接口专门存放常量值
IWeekdayConstants.java
1 | public interface IWeekdayConstants{ |
Test.java
1 | public class Test { |
LindedHashMap中必须用到serialVersionUID,如果没有serialVersionUID字段,则对类的任何更改都将使以前序列化的版本不可读。[注1]
这种方式实现枚举有些问题,就是无法验证需要对比的变量是否合理。如:int day = 7
。
或者仍可以作为其他用途,如:
1 | int man = 1; |
编译通过,但用枚举用途就混乱了。
枚举类
可以通过枚举类型实现上述所有功能,而且功能专用。
1 | public enum Weekday { |
简单的一行代码实现了之前50的功能,能验证合理性,也用途专一,因为类型不同。
Weekday.MON
的类型是Weekday
.
特性
enum定义的类型就是class,enum类编辑的class类似于这样:
1 | public final class Weekday extends Enum { |
- 隐藏构造方法,使得每个实例都是唯一的。
- 定义的
enum
类型总是继承自java.lang.Enum
,且无法被继承; - 只能定义出
enum
的实例,而无法通过new
操作符创建enum
的实例; - 可以将
enum
类型用于switch
语句。
枚举类是一种引用类型,引用类型需要使用equals
来进行比较,如果使用==
则比较的是两个对象是否相等。
但枚举类是一个特殊的引用类型,因为在虚拟机内存中只存在唯一实例,所以使用==
比较也是可以的。
方法
name()
1 | String name = Weekday.MON.name();//"MON" |
ordinal()
1 | int num = Weekday.MON.ordinal();//1 |
这个顺序根据常量在类中的顺序,类似于LinkedMap;
如果使用这个方法做逻辑,之后类中常量的顺序又改变了,倒是程序出问题,强壮性很低。
扩展枚举类
但可以稍微改造下枚举类
1 | public enum Weekday { |
既然可以加逻辑顺序,那岂不是还可以加别的信息呢?
1 | public enum Weekday { |
默认的toString()和name()返回结果是一样的,但是添加逻辑属性之后你就可以通过重写toString()来返回想要的值。
1 | public enum Weekday { |
switch
switch的用法和上面接口的实现方式一样,最后需要加上default放值漏写某一枚举常量;
Test.java
1 | public class Test { |