当前位置: 首页 > article >正文

数据结构:枚举

概念


枚举主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式:

比如下面的例子:

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

利用常量表示RED,GREEN,BLACK既繁琐又容易出错

如果程序里面还有一个int a = 1,那程序可能会认为是RED,用枚举来组织可以轻松解决这些问题

public enum TestEnum {
    RED,BLACK,GREEN;
}

创建枚举类


使用

1.用switch语句来匹配对应的颜色

public enum TestEnum {
    RED,GREEN,BLACK;

    public static void main(String[] args) {
        TestEnum color = RED;//定义目标颜色
        switch(color){
            case GREEN:
                System.out.println("GREEN");
                break;
            case RED:
                System.out.println("RED");
                break;
            case BLACK:
                System.out.println("BLACK");
                break;
            default:
                System.out.println("error");
                break;
        }
    }
}

2.常用方法

方法名称

描述

values()

以数组的形式返回枚举成员

ordinal()

获取枚举成员索引位置

valueOf()

将普通字符串转成枚举实例

compareTo()

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

这些方法是被继承过来的,默认继承于枚举类

但是我们在这里面没有找到values,那这个方法怎么可以被调用呢?

这是由于java编译器在对enum关键字进行处理时,实际上是将enum转换成为了java.lang.Enum类的一个子类来完成,而这个子类中含有values()静态方法。这一点,可以通过反编译enum类来查看。

如图,通过javap反编译enum枚举类,可以看到编译器在对enum处理时,实际上是转换成了Enum的一个子类来实现的,里面可以看到有values()静态方法的声明。


枚举的构造方法

⚠枚举构造方法默认是private的,所以写不写private没影响

    RED(1,"红色"),
    GREEN(2,"绿色"),
    BLACK(3,"黑色");
    private int ordinal;
    private String color;
    TestEnum(int ordinal, String color){
        this.ordinal = ordinal;
        this.color = color;
    }

这也是枚举本身的一个缺点,它无法继承也无法扩展


枚举和反射

既然枚举里面的构造方法是私有的,那我们可不可以用反射来实例化一个枚举对象呢?

我们来试试看

    public static void func() throws ClassNotFoundException, NoSuchMethodException,
            InvocationTargetException, InstantiationException,
            IllegalAccessException {
        //反射Enum类
        Class<?> c1 = Class.forName("demo2.TestEnum");
        //获取Enum类里面私有变量的类型
        Constructor<?> constructor = c1.getDeclaredConstructor(int.class, String.class);
        constructor.setAccessible(true);//私有的要设置true,允许获取
        //实例化新对象
        TestEnum testEnum = (TestEnum) constructor.newInstance(6,"棕色");
        System.out.println(testEnum);
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            InvocationTargetException, InstantiationException,
            IllegalAccessException {
        func();
    }

当我们运行起来的时候,发现程序报错了

报错信息说我没有int, java.lang.String这两个参数

诶我在前面的构造方法不是传入这两个参数了吗?

其实我一开始写的TestEnum是继承于Enum这个类的,相当于我们既要反射TestEnum类,也要反射Enum类

(Enum里面的构造函数)

也就是说我们在c1.getDeclaredConstructor()里面传入四个参数,🆗我照做

但是怎么又抛了一个异常给我

我们点开Constructor的源码,注意到这句话

这句话意思是当我们试图创建一个枚举类时,程序就会抛一个异常出来,不允许我们创建这个类

所以不可以用反射来实例化一个枚举对象

换句话说,枚举十分安全。特别地,用枚举来实现单例模式非常安全


http://www.kler.cn/news/135660.html

相关文章:

  • 图片降噪软件 Topaz DeNoise AI mac中文版功能
  • Chrome添加扩展程序
  • [AI]ChatGPT4 与 ChatGPT3.5 区别有多大
  • 重要功能丨支持1688API接口接入一键跨境铺货及采购,解决跨境卖家货源烦恼!
  • 【数据结构初阶】双链表
  • 多因素方差分析(Multi-way Analysis of Variance) R实现
  • 栈和队列知识点+例题
  • 中国农业开启加速度,龙江农业迎来黄金期
  • 二阶段提交
  • thonny的汉字编码是UTF-8,如何才能转为GB2312?
  • LeetCode - 622. 设计循环队列(C语言,顺序存储结构,配图)
  • 逻辑漏洞(越权)
  • MySQL 的执行原理(五)
  • AI 游戏工具收集
  • 设计模式(二)-创建者模式(1)-单例模式
  • uniapp Android如何授权打开系统蓝牙Bluetooth?
  • 【ES6标准入门】JavaScript中的模块Module语法的使用细节:export命令和imprt命令详细使用,超级详细!!!
  • vue统一登录
  • C# 依赖注入如何实现
  • 数据结构【DS】栈
  • 音视频项目—基于FFmpeg和SDL的音视频播放器解析(十三)
  • 二维偏序问题
  • 从傅里叶变换,到短时傅里叶变换,再到小波分析(CWT),看这一篇就够了(附MATLAB傻瓜式实现代码)
  • 多维时序 | MATLAB实现PSO-BiGRU-Attention粒子群优化双向门控循环单元融合注意力机制的多变量时间序列预测
  • 毕业设计ASP.NET 2368酒店信息管理系统【程序源码+文档+调试运行】
  • 腐蚀监测常用技术及作用
  • 解决word之间复制公式时,公式编辑器变成图片
  • 【算法】堆排序
  • (BMS)电池管理系统技术研究与仿真
  • Selenium安装WebDriver最新Chrome驱动(含116/117/118/119)