目录

Java中的枚举类型Enum

Java中的枚举类型——Enum

一、认识枚举

枚举是在JDK1.5后引入的,主要作用是将一组常量组织起来进行统一管理。

应用场景:错误状态码、消息类型、颜色划分……

自定义的枚举类都会默认继承于java.lang.Enum,因此自定义的枚举类就可以使用Enum类中的方法:

Enum中的常用方法
方法名称作用
values()以数组的形式返回枚举类型中的所有成员
ordinal()获取枚举成员的索引位置
valueOf()将普通字符串转换为枚举实例
compareTo()比较两个枚举成员的定义顺序

注意: values()方法比较特殊,代码在编译后才会自动生成这个方法,所以我们在编写代码时是看不到这个方法的源码的。

二、枚举的使用

我们先自定义一个简单的枚举类:

public enum TestEnum {
    RED,GREEN,BLUE,YELLOW;
}

1、switch语句的判定

枚举对象可以用于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;
    }
}

代码运行结果:

https://i-blog.csdnimg.cn/blog_migrate/818f1e6d69b4f18a4a7676aebb8c7f1d.png

2、values()方法和ordinal()方法的使用

    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());
        }
    }

代码运行结果:

https://i-blog.csdnimg.cn/blog_migrate/b1b05220e6c476723f778834da9a8b5e.png

3、valueOf()方法的使用

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"));
}

代码运行结果:

https://i-blog.csdnimg.cn/blog_migrate/b408a41d09c6e120cc2fb48755d7feb2.png

4、compareTo方法的使用

public static void main(String[] args) {
    System.out.println(RED.compareTo(GREEN));
    System.out.println(BLUE.compareTo(YELLOW));
    System.out.println(YELLOW.compareTo(RED));
}

代码运行结果:

https://i-blog.csdnimg.cn/blog_migrate/66d03b518f449b843406ca669b94d9a2.png

5、枚举类的构造方法

枚举类中的构造方法默认是一个无参的构造方法,我们也可以自定义构造方法:

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

修饰的,如果改为其它的访问权限会报错。

https://i-blog.csdnimg.cn/blog_migrate/4974b1cc319ec9fb3083051d08e4c718.png

三、枚举和反射

既然枚举类型的构造方法默认是被

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中只有一个构造方法:

https://i-blog.csdnimg.cn/blog_migrate/416808be3d4b68c64c0b80c398d09212.png

我们在构造子类对象之前需要先帮助父类构造,所以调用 getDeclaredConstructor

方法时需要给4个参数,2个是自定义枚举类TestEnum构造方法的参数类型,2个是父类Enum构造方法的参数类型。

代码运行结果:

https://i-blog.csdnimg.cn/blog_migrate/fe9b55d7e55e67010a5036cf45f19ae8.png

抛出 IllegalArgumentException 异常,并提示说:

Cannot reflectively create enum objects,

即 不能反射式创建enum对象 。