做网站公司的收费多少,免费建站工具,中国各大网站,中国徐州网文章目录 #x1f384;枚举的背景及定义⚾枚举特性总结#xff1a; #x1f332;枚举的使用#x1f6a9;switch语句#x1f6a9;常用方法#x1f4cc;示例一#x1f4cc;示例二 #x1f38d;枚举优点缺点#x1f334;枚举和反射#x1f6a9;枚举是否可以通过反射枚举的背景及定义⚾枚举特性总结 枚举的使用switch语句常用方法示例一示例二 枚举优点缺点枚举和反射枚举是否可以通过反射拿到实例对象呢 枚举总结⭕总结 枚举的背景及定义
枚举是在JDK1.5以后引入的。主要用途是将一组常量组织起来在这之前表示一组常量通常使用定义常量的方式
public static final int RED 1;
public static final int GREEN 2;
public static final int BLACK 3;但是常量举例有不好的地方例如可能碰巧有个数字1但是他有可能误会为是RED现在我们可以直接用枚举来进行组织这样一来就拥有了类型枚举类型。而不是普通的整形1
public enum TestEnum {RED,BLACK,GREEN;
}⚾枚举特性总结 优点将常量组织起来统一进行管理 场景错误状态码消息类型颜色的划分状态机等等… 本质是 java.lang.Enum 的子类也就是说自己写的枚举类就算没有显示的继承 Enum 但是其默认继承了这个类
枚举的使用
switch语句
public enum TestEnum {RED,BLACK,GREEN,WHITE;public static void main(String[] args) {TestEnum testEnum2 TestEnum.BLACK;switch (testEnum2) {case RED:System.out.println(red);break;case BLACK:System.out.println(black);break;case WHITE:System.out.println(WHITE);break;case GREEN:System.out.println(black);break;default:break;}}
}常用方法
Enum 类的常用方法
示例一 /*** Created with IntelliJ IDEA.* Description:* User: GAOBO* Date: 2020-02-06* Time: 16:19*/
public enum TestEnum {RED, BLACK, GREEN, WHITE;public static void main(String[] args) {TestEnum[] testEnum2 TestEnum.values();for (int i 0; i testEnum2.length; i) {System.out.println(testEnum2[i] testEnum2[i].ordinal());}System.out.println();System.out.println(TestEnum.valueOf(GREEN));}
}示例二 /*** Created with IntelliJ IDEA.* Description:* User: GAOBO* Date: 2020-02-06* Time: 16:19*/
public enum TestEnum {RED,BLACK,GREEN,WHITE;public static void main(String[] args) {
//拿到枚举实例BLACKTestEnum testEnum TestEnum.BLACK;
//拿到枚举实例REDTestEnum testEnum21 TestEnum.RED;System.out.println(testEnum.compareTo(testEnum21));System.out.println(BLACK.compareTo(RED));System.out.println(RED.compareTo(BLACK));}
}刚刚说过在Java当中枚举实际上就是一个类。所以我们在定义枚举的时候还可以这样定义和使用枚举 /*** Created with IntelliJ IDEA.* Description:* User: GAOBO* Date: 2020-02-06* Time: 16:19*/
public enum TestEnum {RED(red,1),BLACK(black,2),WHITE(white,3),GREEN(green,4);private String name;private int key;/*** 1、当枚举对象有参数后需要提供相应的构造函数* 2、枚举的构造函数默认是私有的 这个一定要记住* param name* param key*/private TestEnum (String name,int key) {this.name name;this.key key;}public static TestEnum getEnumKey (int key) {for (TestEnum t: TestEnum.values()) {if(t.key key) {return t;}} return null;}public static void main(String[] args) {System.out.println(getEnumKey(2));}
}注意枚举的构造方法默认是私有的
枚举优点缺点
优点 枚举常量更简单安全 。 枚举具有内置方法 代码更优雅
缺点
不可继承无法扩展
枚举和反射
枚举是否可以通过反射拿到实例对象呢
博主在反射里讲过了任何一个类哪怕其构造方法是私有的我们也可以通过反射拿到他的实例对象
那么枚举的构造方法也是私有的我们是否可以拿到呢
接下来我们来实验一下
同样利用上述提供的枚举类来进行举例
import java.lang.reflect.Constructor;/*** Created with IntelliJ IDEA.* Description:* User: GAOBO* Date: 2020-02-24* Time: 16:13*/
public enum TestEnum {RED(red,1),BLACK(black,2),WHITE(white,3),GREEN(green,4);private String name;private int key;
/*** 1、当枚举对象有参数后需要提供相应的构造函数* 2、枚举的构造函数默认是私有的 这个一定要记住* param name* param key*/
private TestEnum (String name,int key) {this.name name;this.key key;
}public static TestEnum getEnumKey (int key) {for (TestEnum t: TestEnum.values()) {if(t.key key) {return t;}}return null;}public static void reflectPrivateConstructor() {try {Class? classStudent Class.forName(TestEnum);
//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类是提供了两个参数分别是String和int。Constructor? declaredConstructorStudent classStudent.getDeclaredConstructor(String.class,int.class);
//设置为true后可修改访问权限declaredConstructorStudent.setAccessible(true);Object objectStudent declaredConstructorStudent.newInstance(绿色,666);TestEnum testEnum (TestEnum) objectStudent;System.out.println(获得枚举的私有构造函数testEnum);} catch (Exception ex) {ex.printStackTrace();}}public static void main(String[] args) {reflectPrivateConstructor();}
}输出结果为 我们看到异常信息是 java.lang.NoSuchMethodException: TestEnum.(java.lang.String, int) 什么意思是 就是没有对应的构造方法
可是我们提供的枚举的构造方法就是两个参数分别是 String 和 int 那么问题出现在哪里呢还记不记得我们说过的我们所有的枚举类都是默认继承与 java.lang.Enum
说到继承继承了什么继承了父类除构造函数外的所有东西并且子类要帮助父类进行构造而我们写的类并没有帮助父类构造
那意思是我们要在自己的枚举类里面提供super吗不是的枚举比较特殊虽然我们写的是两个但是默认他还添加了两个参数哪两个参数呢我们看一下Enum类的源码
protected Enum(String name, int ordinal) {this.name name;this.ordinal ordinal;
}也就是说我们自己的构造函数有两个参数一个是String一个是int同时他默认后边还会给两个参数一个是String一个是int。也就是说这里我们正确给的是4个参数 public static void reflectPrivateConstructor() {try {Class? classStudent Class.forName(TestEnum);
//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类是提供了两个参数分别是String和int。Constructor? declaredConstructorStudent classStudent.getDeclaredConstructor(String.class,int.class,String.class,int.class);
//设置为true后可修改访问权限declaredConstructorStudent.setAccessible(true);
//后两个为子类参数大家可以将当前枚举类的key类型改为double验证Object objectStudent declaredConstructorStudent.newInstance(父类参数,666,子类参数,888);TestEnum testEnum (TestEnum) objectStudent;System.out.println(获得枚举的私有构造函数testEnum);} catch (Exception ex) {ex.printStackTrace();}}此时运行程序结果是 java.lang.IllegalArgumentException: Cannot reflectively create enum objects at java.lang.reflect.Constructor.newInstance(Constructor.java:416) at TestEnum.reflectPrivateConstructor(TestEnum.java:46) at TestEnum.main(TestEnum.java:55) 嗯没错他还报错了不过这次就是我想要的结果此时的异常信息显示是我的一个方法这个方法是newInstance() 报错了
没错问题就是这里我们来看一下这个方法的源码为什么会抛出 java.lang.IllegalArgumentException: 异常呢
接下来我们再看一下newInstance() 的源码 这里我们会发现
枚举在这里被过滤了你不能通过反射获取枚举类的实例
枚举总结 枚举本身就是一个类其构造方法默认为私有的且都是默认继承与 java.lang.Enum 枚举可以避免反射和序列化问题
⭕总结
关于《【javaSE】 枚举与枚举的使用》就讲解到这儿感谢大家的支持欢迎各位留言交流以及批评指正如果文章对您有帮助或者觉得作者写的还不错可以点一下关注点赞收藏支持一下