前言
最近写代码,对常量的处理,遇见两种方式:常量类和枚举类。
现根据自己项目中的一些使用情况对二者进行简单的使用分析,然后系统梳理下枚举类的相关基础知识。
1、枚举类和常量类的区别
区别1:
假如有下面方法:根据性别推荐商品
使用枚举的话:
方法定义:
recommendBySex(Customer sex)
方法调用:
xxx.recommendBySex(MAN);
使用常量的话:
方法定义:
recommendBySex(int sex)
方法调用:
xxx.recommendBySex(SexConstant.MAN);
分析:
如果recommendBySex方法注释缺失,那么使用者调用recommendBySex(Enum sex)方法时必然可以知道这里使用了常量,而调用recommendBySex(int sex)方法时,就无法确定这里到底是传规定的常量值还是其他int类型的值。从这一点上来看,使用Enum可以使得方法定义更为清晰。
区别2:
假如有以下场景:
需要将学生类别这一概念以某些规则建立为常量,例如:男-近视、男-视力正常、女-近视、女-视力正常
使用枚举的话:
public enum StudentEnum {
S1('M', true), S2('M', false), S3('F', true), S4('F', false);
private final char sex;
private final boolean eyeSight;
private StudentEnum(char sex, boolean eyeSight) {
this.sex = sex;
this.eyeSight = eyeSight;
}
public char getSex() {
return sex;
}
public boolean isEyeSight() {
return eyeSight;
}
}
使用常量类的话:
public class StudentConstant {
private static final Student S1;
private static final Student S2;
private static final Student S3;
private static final Student S4;
static {
S1 = new Student('M', true);
S2 = new Student('M', false);
S3 = new Student('F', true);
S4 = new Student('F', false);
}
}
class Student {
private char sex;
private boolean eyeSight;
public Student(char sex, boolean eyeSight) {
super();
this.sex = sex;
this.eyeSight = eyeSight;
}
}
分析:
显而易见,在处理这种对象形式的常量的时候,枚举更加简洁,直观。
2、枚举实现原理
实际上在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类。
例子:
enum StudentEnum {
S1, S2, S3, S4;
}
javap 反编译后:
Compiled from "StudentEnum.java"
final class nnn.StudentEnum extends java.lang.Enum<nnn.StudentEnum> {
public static final nnn.StudentEnum S1;
public static final nnn.StudentEnum S2;
public static final nnn.StudentEnum S3;
public static final nnn.StudentEnum S4;
public static nnn.StudentEnum[] values();
public static nnn.StudentEnum valueOf(java.lang.String);
static {};
}
- 继承了Enum类
- 每一个常量都是一个static final对象,并且在static块中被初始化。
3、枚举基础使用
Enum类常用方法
方法 | 作用 |
---|---|
int compareTo (E o) | 比较此枚举与指定对象的顺序。 |
boolean equals(Object other) | 当指定对象等于此枚举常量时,返回 true。 |
String toString() | 返回枚举常量的名称,它包含在声明中。 |
int ordinal() | 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零) |
< T extends Enum< T >> T valueOf(Class< T > enumType, String name) | 返回带指定名称的指定枚举类型的枚举常量。 |
枚举专用Map和Set
EnumSet是与枚举类型一起使用的专用 Set 集合;
EnumMap是枚举的专属的集合。
4、实际使用枚举的例子
public enum PackagePidEnum {
//自定义套餐
PACKAGE_CUSTOM(0L),
//套餐A
PACKAGE_A(1L),
//套餐B
PACKAGE_B(2L),
//套餐C
PACKAGE_C(3L),
//基础套餐
PACKAGE_BASIC(4L);
private final Long value;
PackagePidEnum(Long value) {
this.value = value;
}
public Long getValue() {
return value;
}
}