枚举是在JDK1.5后引入的,主要作用是将一组常量组织起来进行统一管理。
应用场景:错误状态码、消息类型、颜色划分……
自定义的枚举类都会默认继承于java.lang.Enum,因此自定义的枚举类就可以使用Enum类中的方法:
Enum中的常用方法 | |
方法名称 | 作用 |
values() | 以数组的形式返回枚举类型中的所有成员 |
ordinal() | 获取枚举成员的索引位置 |
valueOf() | 将普通字符串转换为枚举实例 |
compareTo() | 比较两个枚举成员的定义顺序 |
注意:values()方法比较特殊,代码在编译后才会自动生成这个方法,所以我们在编写代码时是看不到这个方法的源码的。
我们先自定义一个简单的枚举类:
- public enum TestEnum {
- RED,GREEN,BLUE,YELLOW;
- }
枚举对象可以用于switch语句的判定条件:
- public static void main(String[] args) {
- TestEnum test = TestEnum.RED;
- switch (test){
- case RED:
- System.out.println("red");
- break;
- case GREEN:
- System.out.println("green");
- break;
- case BLUE:
- System.out.println("blue");
- break;
- case YELLOW:
- System.out.println("yellow");
- break;
- default:
- break;
- }
- }
代码运行结果:
- public static void main(String[] args) {
- //将自定义枚举类型中的所有对象以数组的形式返回
- TestEnum[] testEnums = TestEnum.values();
-
- for (int i = 0; i < testEnums.length; i++) {
- //输出每个对象及其对应的序号
- System.out.println(testEnums[i]+"序号:"+testEnums[i].ordinal());
- }
- }
代码运行结果:
- public static void main(String[] args) {
- //输入的字符串必须是上面的实例之一
- System.out.println(TestEnum.valueOf("RED"));
- System.out.println(TestEnum.valueOf("GREEN"));
- //否则会抛出IllegalArgumentException异常
- System.out.println(TestEnum.valueOf("BLACK"));
- }
代码运行结果:
- public static void main(String[] args) {
- System.out.println(RED.compareTo(GREEN));
- System.out.println(BLUE.compareTo(YELLOW));
- System.out.println(YELLOW.compareTo(RED));
- }
代码运行结果:
枚举类中的构造方法默认是一个无参的构造方法,我们也可以自定义构造方法:
- public enum TestEnum {
- RED("RED",1),GREEN("GREEN",2),
- BLUE("BLUE",3),YELLOW("YELLOW",4);
-
- public String color;
- public int ordinal;
-
- private TestEnum(String color,int ordinal){
- this.color = color;
- this.ordinal = ordinal;
- }
- }
枚举类型的构造方法默认是被private修饰的,如果改为其它的访问权限会报错。
既然枚举类型的构造方法默认是被private修饰的,那么能否通过反射的方式来实例化一个枚举对象呢?
- public static void main(String[] args) {
-
- //获取TestEnum的Class对象
- Class> c = TestEnum.class;
-
- try {
- //还需要给父类Enum的构造方法进行传参
- Constructor> constructor =
- c.getDeclaredConstructor(String.class,int.class,String.class,int.class);
-
- //设置为true后可以修改访问权限
- constructor.setAccessible(true);
-
- //父类参数不给也可以,默认为空
- TestEnum testEnum =
- (TestEnum) constructor.newInstance("WHITE",5,"父类的参数",999);
-
- System.out.println(testEnum);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
注意:
自定义的枚举类型默认继承于标准库里的Enum类,Enum中只有一个构造方法:
我们在构造子类对象之前需要先帮助父类构造,所以调用getDeclaredConstructor方法时需要给4个参数,2个是自定义枚举类TestEnum构造方法的参数类型,2个是父类Enum构造方法的参数类型。
代码运行结果:
抛出IllegalArgumentException异常,并提示说:Cannot reflectively create enum objects,即不能反射式创建enum对象。