目录
一、枚举的意义
二、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();}
警告:
是在这个函数出错的,我们去看看是什么问题
因为这一条判断语句,枚举类型不能被反射,所以枚举类型是安全的