• 【JavaSE】枚举


    目录

    一、定义

    二、使用

    2.1 switch

    2.2 枚举类的常用方法

    三、是否可以通过反射调用枚举的构造方法创建实例 不可以

    四、枚举的优缺点

    五、用枚举实现单例模式


    一、定义

    Java的枚举是一个特殊的类,一般表示一组常量。类似于26个字母、月份这种有几种固定的取值时,可以将其定义为枚举类型

    定义形式:

    修饰符 enum 枚举类:基础类型{

            枚举成员1,枚举成员2

    }

    1. public enum MyEnum {
    2. Math,English,Chinese
    3. }

    注意事项

    • 任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内
    • 多个枚举成员之间使用逗号分隔。
    • 当有除了枚举成员之外的属性时,枚举成员必须在第一行并用分号结尾
    • 枚举的基础类型可以不显示的声明,即枚举名后可以不加基础类型
    • 如果没有显式地声明枚举的基础类型,那么意味着它所对应的基础类型是 int

    补充:

    • 在Java 中使用 enum 关键字来定义枚举类,其地位与 class、interface 相同
    • 枚举类是一种特殊的类,它和普通的类一样,有自己的成员变量、成员方法、构造方法
    • 枚举类的构造方法默认被 private 修饰(也只能被 private 修饰),所以无法从外部调用构造器(即 Enum 不能实例化),构造器只在构造枚举值时被调用
    • 使用 enum 定义的枚举类默认继承了 java.lang.Enum 类(虽然没有显示继承),并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口
    • 所有的枚举值都是 public static final 的,且非抽象的枚举类不能再派生子类
    • 枚举类的所有实例(枚举值)必须在枚举类的第一行显式地列出,否则这个枚举类将永远不能产生实例。列出这些实例(枚举值)时,系统会自动添加 public static final 修饰,无需程序员显式添加
    • 当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,即枚举值是一个对象
    • 与普通类一样,枚举类也可以实现一个或多个接口。枚举类实现接口时,同样要实现该接口的所有方法

    二、使用

    2.1 switch

    1. public enum MyEnum {
    2. Math,English,Chinese;
    3. public static void main(String[] args) {
    4. MyEnum myEnum = MyEnum.Math;
    5. switch (myEnum){
    6. case Math:
    7. System.out.println("math");
    8. break;
    9. case Chinese:
    10. System.out.println("Chinese");
    11. break;
    12. case English:
    13. System.out.println("english");
    14. break;
    15. }
    16. }
    17. }

    2.2 枚举类的常用方法

    方法用途
    values()以数组形式返回枚举类型的所有成员
    ordinal()获取枚举成员的索引位置
    valueOf()将普通字符串转换为枚举实例
    compareTo()比较两个枚举成员在定义时的顺序
    1. public enum MyEnum {
    2. Math,English,Chinese;
    3. public static void main(String[] args) {
    4. MyEnum[] myEnums = MyEnum.values();
    5. for (int i = 0; i < myEnums.length; i++) {
    6. System.out.println(myEnums[i] +"下标是:"+ myEnums[i].ordinal());
    7. }
    8. }
    9. }

    1. public enum MyEnum {
    2. Math,English,Chinese;
    3. public static void main(String[] args) {
    4. System.out.println(Math.compareTo(English)); // -1
    5. System.out.println(Math.compareTo(Chinese)); // -2
    6. }
    7. }
    1. public enum MyEnum {
    2. Math,English,Chinese;
    3. public static void main(String[] args) {
    4. System.out.println(MyEnum.valueOf("Math"));
    5. System.out.println(MyEnum.valueOf("Math1"));
    6. }
    7. }

    三、是否可以通过反射调用枚举的构造方法创建实例 不可以

    1. public enum MyEnum {
    2. Math("Math",1),English("English",2),Chinese("Chinese",3);
    3. private String name;
    4. private int key;
    5. /**
    6. * 当枚举对象有参数后,需要提供相应的构造函数
    7. * 枚举的构造函数默认是私有的
    8. * @param name
    9. * @param key
    10. */
    11. private MyEnum(String name,int key){
    12. this.name = name;
    13. this.key = key;
    14. }
    15. public static void main(String[] args) {
    16. try {
    17. Class c1 = Class.forName("demo2.MyEnum");
    18. Constructor constructor = c1.getDeclaredConstructor(String.class,int.class);
    19. constructor.setAccessible(true);
    20. MyEnum myEnum = (MyEnum)constructor.newInstance("Java",12);
    21. System.out.println(myEnum);
    22. } catch (ClassNotFoundException e) {
    23. e.printStackTrace();
    24. } catch (NoSuchMethodException e) {
    25. e.printStackTrace();
    26. } catch (IllegalAccessException e) {
    27. e.printStackTrace();
    28. } catch (InstantiationException e) {
    29. e.printStackTrace();
    30. } catch (InvocationTargetException e) {
    31. e.printStackTrace();
    32. }
    33. }
    34. }

    报异常:没有对应的构造方法

    原因:自定义的枚举类,都是默认继承java.lang.Enum。因此,需要帮助父类进行构造。

    解决方案1:适用super 不可行

    解决方案2:枚举的构造函数虽然我们只写了两个,但是默认还添加了两个,因此一共有四个。默认添加的参数通过源码可以看到:

    1. Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,String.class,int.class);
    2. constructor.setAccessible(true);
    3. MyEnum myEnum = (MyEnum)constructor.newInstance("Java",12,"父类的参数",1);
    4. System.out.println(myEnum);

     

    原因:

    四、枚举的优缺点

    • 优点:枚举常量更简单、更安全、枚举具有内置方法
    • 缺点:枚举不可以继承、枚举无法扩展

    五、用枚举实现单例模式

    1. public enum TestEnum {
    2. INSTANCE;
    3. public TestEnum getInstance(){
    4. return INSTANCE;
    5. }
    6. public static void main(String[] args) {
    7. TestEnum testEnum1 = INSTANCE.getInstance();
    8. TestEnum testEnum2 = INSTANCE.getInstance();
    9. System.out.println(testEnum1 == testEnum2); // true
    10. }
    11. }

  • 相关阅读:
    LeetCode_哈希表_简单_594.最长和谐子序列
    最新腾讯面试题汇总--C++后端开发岗(部分含答案)
    二分类问题的解决利器:逻辑回归算法详解(一)
    CentOS 更新yum源
    算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient
    mac M1上的效率工具——Alfred(附M1配置workflows)
    Kubernetes使用OkHttp客户端进行网络负载均衡
    MySQL全库只读,不推荐使用set global readonly=true
    华为防火墙基础自学系列 | 证书申请方式
    获取并导入Mybtis源码到Idea &&HSQLDB数据库简介
  • 原文地址:https://blog.csdn.net/weixin_44258092/article/details/126561844