当前位置: 首页 > 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/a/135660.html

相关文章:

  • 【机器学习】机器学习中用到的高等数学知识-3.微积分 (Calculus)
  • WebStorm 如何调试 Vue 项目
  • Linux——gcc编译过程详解与ACM时间和进度条的制作
  • Redis五种数据类型剖析
  • go语言 分布式一致
  • 【系统架构设计师】真题论文: 论软件可靠性设计与应用(包括解题思路和素材)
  • 图片降噪软件 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】栈