JAVA-枚举的使用

目录

一、枚举的意义

二、enum类的使用

1.switch

2.常用方法

2.1 values() 和 ordinal()

2.1.1 Enum基本介绍

2.2 valueOf()

2.3 compareTo()

三、枚举的优点和缺点

四、枚举安全在什么地方


一、枚举的意义

public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLACK = 3;

让常量有类型,虽然final修饰的也可以做为常量但是如果代码其他地方有用到常量1,而不是代表RED那就会混淆意思。这个时候我们就可以用枚举。

public enum TestEnum {
    RED,BLACK,GREEN;
}
优点:将常量组织起来统一进行管理
场景:错误状态码,消息类型,颜色的划分,状态机等等 ....
注意:
枚举类型默认继承了   java.lang.Enum ,也就是说,自己写的枚举类,就算没有显示的继承 Enum ,但是其默认继承了 这个类。

二、enum类的使用

1.switch

public static void main(String[] args) {

        EnumTest enumTest = RED;
        switch (enumTest) {
            case RED -> System.out.println(RED);
            case BLACK -> System.out.println(BLACK);
            case GREEN -> System.out.println(GREEN);
        }

        //输出RED

}

2.常用方法

Enum类的常用方法:

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

2.1 values() 和 ordinal()

    public static void main2(String[] args) {
        EnumTest[] enumTests = EnumTest.values();

        for (int i = 0; i < enumTests.length; i++) {
            System.out.print(enumTests[i] + " " + enumTests[i].ordinal() + "\n");
        }
    }

结果:

2.1.1 Enum基本介绍

Enum的构造方法

Enum类只有这一个构造方法,但是我们写的枚举类并没有写构造方法,我们知道如果我们没写构造方法,会有一个没有任何参数的构造方法。但是父类只有这两个参数的构造方法。其实也是帮我们写了有两个参数的方法,传的值是null。所以枚举类是比较特殊的

如果我们自己创建一个构造方法:

  • 构造函数是
  • zh当枚举对象有参数后,需要提供相应的构造函数
    public enum EnumTest {
        
        //有了自己的构造方法,就必须在这里写的时候带参数
        RED("red",0),BLACK("black",1),GREEN("green",2);
    
        private String name;
        private int key;
        /**
         * 1、当枚举对象有参数后,需要提供相应的构造函数
         * 2、枚举的构造函数默认是私有的 这个一定要记住
         * @param name
         * @param key
         */
        private EnumTest(String name, int key) {
            this.name = name;
            this.key = key;
        }
    }

注意: 枚举内是不能手动创建对象的

那么问题来了,不创建对象怎么调用构造方法?

这也是为什么被说为是:枚举对象

name就做为名字,ordinal就做为创建的顺序。

我们也可以通过调试看看刚刚创建的数组是怎么样表示的:

ordinal()就是直接返回的ordinal

2.2 valueOf()

将普通字符串转换为枚举实例

字符串必须的以有的枚举对象,如果不是枚举对象会报错

public enum EnumTest {
    RED("red",0),BLACK("black",1),GREEN("green",2);

    public static void main(String[] args) {
        EnumTest val = EnumTest.valueOf("BLACK");
        System.out.println(val);

    }
}

如果不是枚举对象: 

结果:

2.3 compareTo()

比较两个枚举成员在定义时的顺序

public static void main(String[] args) {

        //方式1 适合在枚举类内部使用
        System.out.println(RED.compareTo(BLACK));

        //方式2 适合在枚举类外时使用
        EnumTest enumTest1 = EnumTest.RED;
        EnumTest enumTest2 = EnumTest.BLACK;
        
        System.out.println(enumTest1.compareTo(enumTest2));
}

结果:

根据ordinal的值比较 

三、枚举的优点和缺点

优点:
1. 枚举常量更简单安全 。
2. 枚举具有内置方法 ,代码更优雅
缺点:
1. 不可继承,无法扩展

四、枚举安全在什么地方

我们知道利用反射无论是否是私有的,都可以被反射拿到甚至更改但是枚举是不可以的。

    public static void reflectPrivateConstructor() {

        Class<?> c1 = null;
        try {
            c1 = Class.forName("EnumTest");
            //拿到构造方法
            Constructor<EnumTest> constructor =
                    (Constructor<EnumTest>)c1. 
         //前两个传的是父类的构造方法参数,和两个是子类的构造方法参数  
         getDeclaredConstructor(String.class,int.class,String.class,int.class);
            
            constructor.setAccessible(true);
            //创建类的实例
            EnumTest testEnum = constructor.newInstance("test",10,"白色",19);

            System.out.println(testEnum);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main4(String[] args) {
        reflectPrivateConstructor();
    }

警告: 

 是在这个函数出错的,我们去看看是什么问题

 因为这一条判断语句,枚举类型不能被反射,所以枚举类型是安全的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值