【Java】Enum 枚举

news2024/11/20 12:22:55

java 中的枚举类型本质是默认继承于 java.lang.Enum 的类

常用方法

方法签名描述
values()以数组形式返回枚举类型的所有成员
ordinal()获取枚举成员的索引位置(编号、序号)
valueOf()将普通字符串转换为枚举实例
compareTo()比较两个枚举成员在定义是的顺序

枚举示例

颜色枚举类

注意:

枚举的构造方法默认是私有的,其他类无法调用

枚举类会列出所有的可能枚举值,不需要再进行扩展与继承,且枚举值是不可变的。因此枚举类无需被继承/扩展,如果允许继承/拓展,可能会破坏枚举值的不可变性

public enum ColorEnum {
    // 带属性枚举成员
    RED("红色", 1),
    GREEN("绿色", 2),
    BLUE("蓝色", 3);

    // 属性
    private String color;
    private int key;

    // 枚举构造方法默认私有
    private ColorEnum(String color, int key) {
        this.color= color;
        this.key = key;
    }

    // 展示枚举成员的属性
    public void show() {
        System.out.println(key + " " + color);
    }

    // 输出所有枚举成员名
    public static void names() {
        // 使用 for each 遍历 values 结果集
        for (ColorEnum colorEnum : ColorEnum.values()) {
            // 使用 name() 获取枚举成员名
            System.out.print(colorEnum.name() + " ");
        }
        System.out.println();
    }

    // 输出所有枚举成员的 ordinal
    public static void ordinals() {
        // 使用 for each 遍历 values 结果集
        for (ColorEnum colorEnum : ColorEnum.values()) {
            // 使用 ordinal() 获取枚举成员的索引位置
            System.out.print(colorEnum.ordinal() + " ");
        }
        System.out.println();
    }
}

测试枚举类

调用我们自定义的静态方法

ColorEnum.ordinals();
ColorEnum.names();

使用 valueOf(枚举成员名) 获取枚举对象

ColorEnum red = ColorEnum.valueOf("RED");
ColorEnum green = ColorEnum.valueOf("GREEN");
ColorEnum blue = ColorEnum.valueOf("BLUE");

// 调用自定义的属性展示方法
red.show();
green.show();
blue.show();

使用 .枚举成员 的方式获取枚举对象

red = ColorEnum.RED;
green = ColorEnum.GREEN;
blue = ColorEnum.BLUE;

// 调用自定义的属性展示方法
red.show();
green.show();
blue.show();

使用 compareTo() 比较索引位置关系

System.out.println(
    red.compareTo(red) + " " +
    red.compareTo(green) + " " +
    red.compareTo(blue)
);

枚举与反射

枚举类型的构造方法是私有的,那我们能不能通过反射去获取进而构造枚举实例呢?毕竟反射可以无视访问修饰符嘛,现在我们可以来尝试一下

Class colorEnumClass = Class.forName("ColorEnum");

Constructor colorEnumDeclaredConstructor = 
    colorEnumClass.getDeclaredConstructor(
        String.class, int.class
    );

ColorEnum colorEnum = 
    (ColorEnum) colorEnumDeclaredConstructor.newInstance(
        "红色", 1
    );

System.out.println(colorEnum);

结果显示为找不到 ColorEnum(java.lang.String, int) 的构造方法,但我们明明写了这样的构造方法

ColorEnum(String color, int key) {
    this.color = color;
    this.key = key;
}

这是应为枚举类型的构造方法会有带有两个默认传给父类的构造参数 name 和 ordinal

/**
* Sole constructor.  Programmers cannot invoke this constructor.
* It is for use by code emitted by the compiler in response to
* enum type declarations.
*
* @param name - The name of this enum constant, which is the identifier
*               used to declare it.
* @param ordinal - The ordinal of this enumeration constant (its position
*         in the enum declaration, where the initial constant is assigned
*         an ordinal of zero).
*/
protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
}

因此我们的构造方法应该是 ColorEnum(java.lang.String, int, java.lang.String, int)

Constructor colorEnumDeclaredConstructor = 
    colorEnumClass.getDeclaredConstructor(
        String.class, int.class, String.class, int.class
    );

ColorEnum colorEnum = 
    (ColorEnum) colorEnumDeclaredConstructor.newInstance(
        "红色", 1, "RED", 0
    );

这次 NoSuchMethodException 没有出现了,只是告诉我们 IllegalAccessException 非法访问异常,我们可以修改一下访问权限

Constructor colorEnumDeclaredConstructor = 
    colorEnumClass.getDeclaredConstructor(
        String.class, int.class, String.class, int.class
    );

// 修改访问权限为允许
colorEnumDeclaredConstructor.setAccessible(true);

ColorEnum colorEnum = 
    (ColorEnum) colorEnumDeclaredConstructor.newInstance(
        "红色", 1, "RED", 0
    );

结果还是不行,告诉我们不能用反射创建枚举对象。这是因为枚举的定义就不允许她新建实例,枚举类型的实例的有限的、固定的,不能随意创建新的实例。如果允许反射创建新的实例,这就会破坏枚举类型的不可变性和安全性。于是,Java 直接在 newInstance() 源码中,将枚举类型给过滤掉了

if ((clazz.getModifiers() & Modifier.ENUM) != 0) {
    throw new IllegalArgumentException(
        "Cannot reflectively create enum objects"
    );
}
/**
* Uses the constructor represented by this {@code Constructor} object to
* create and initialize a new instance of the constructor's
* declaring class, with the specified initialization parameters.
* Individual parameters are automatically unwrapped to match
* primitive formal parameters, and both primitive and reference
* parameters are subject to method invocation conversions as necessary.
*
* <p>If the number of formal parameters required by the underlying constructor
* is 0, the supplied {@code initargs} array may be of length 0 or null.
*
* <p>If the constructor's declaring class is an inner class in a
* non-static context, the first argument to the constructor needs
* to be the enclosing instance; see section 15.9.3 of
* <cite>The Java&trade; Language Specification</cite>.
*
* <p>If the required access and argument checks succeed and the
* instantiation will proceed, the constructor's declaring class
* is initialized if it has not already been initialized.
*
* <p>If the constructor completes normally, returns the newly
* created and initialized instance.
*
* @param initargs array of objects to be passed as arguments to
* the constructor call; values of primitive types are wrapped in
* a wrapper object of the appropriate type (e.g. a {@code float}
* in a {@link java.lang.Float Float})
*
* @return a new object created by calling the constructor
* this object represents
*
* @exception IllegalAccessException    if this {@code Constructor} object
*              is enforcing Java language access control and the underlying
*              constructor is inaccessible.
* @exception IllegalArgumentException  if the number of actual
*              and formal parameters differ; if an unwrapping
*              conversion for primitive arguments fails; or if,
*              after possible unwrapping, a parameter value
*              cannot be converted to the corresponding formal
*              parameter type by a method invocation conversion; if
*              this constructor pertains to an enum type.
* @exception InstantiationException    if the class that declares the
*              underlying constructor represents an abstract class.
* @exception InvocationTargetException if the underlying constructor
*              throws an exception.
* @exception ExceptionInInitializerError if the initialization provoked
*              by this method fails.
*/
@CallerSensitive
public T newInstance(Object ... initargs)
    throws InstantiationException, IllegalAccessException,
           IllegalArgumentException, InvocationTargetException
{
    if (!override) {
        if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            checkAccess(caller, clazz, null, modifiers);
        }
    }
    if ((clazz.getModifiers() & Modifier.ENUM) != 0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");
    ConstructorAccessor ca = constructorAccessor;   // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }
    @SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(initargs);
    return inst;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/502227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

名称空间(namespaces)与作用域

引入 在python解释器中运行一行代码import this就可以看到“传说”中的python之禅&#xff0c;它体现了使用python进行开发的规范&#xff0c;而最后一句 - Namespaces are one honking great idea -- lets do more of those!就是本文的主角。 名称空间(Namespaces) 名称空间…

PointNet:利用深度学习对点云进行3D分类和语义分割

PointNet&#xff1a;利用深度学习对点云进行3D分类和语义分割 参考自&#xff0c;PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation 代码仓库地址为&#xff1a;https://github.com/charlesq34/pointnet/ 介绍 这次介绍的是一个比较基础的工作…

部署博客系统(部署博客系统到云服务器)

目录 1、建库建表 2、微调本地代码 3、打包&#xff08;使用Maven打成war包&#xff09; 4、拷贝到Tomcat的webapps 5、启动Tomcat服务器&#xff08;只有启动成功了才能进行访问&#xff09; 6、访问博客系统 1、建库建表 云服务器访问的是云服务器上的数据库,不是…

FFmpeg YUV 编码 H264

1. x264 库 由于 FFmpeg 不支持 h264 编码,所以需要集成 x264 库,现在使用的是当前最新版本 1.1 官方下载地址: videolanhttps://www.videolan.org/developers/x264.html 1.2 编译脚本地址: x264-ioshttps://github.com/kewlbear/x264-

【信息系统项目管理师】概要和框架-2023年5月7日总结

还有20天考试&#xff0c;记录下这二十天的学习内容。 今天之前4月4日到4月13日五天修炼看了一半&#xff0c;看到了项目风险管理&#xff0c;云里雾里看了个大概。 听野人老师的课从第一章跟着到了第十章&#xff0c;听一会儿就走神&#xff0c;听一会儿就走神。 改变思路&…

1.4 初探Spring - 采用Java配置类管理Bean

一、采用Java配置类管理Bean 1、打开项目 Maven项目 - SpringDemo 2、创建子包 在net.hf.spring包里创建day04子包 3、创建杀龙任务类 在day04子包里创建杀龙任务类 - SlayDragonQuest package net.hf.spring.day04;/*** 功能&#xff1a;杀龙任务类* 作者&#xff1…

Ubuntu搭建VPN服务

PPTD协议 此协议据说安全级别不高&#xff0c;苹果系统已经不支持&#xff0c;但windows依然支持 1.安装,root账号登录服务器 apt-get update apt-get install pptpd 2.配置主机ip及连接主机的设备所分配ip池,客户端分配的内网ip段。 vim /etc/pptpd.conf 将以下两行注释去…

同云跨可用区备份容灾解决方案详解

云可用区 云可用区&#xff08;Availability Zone,AZ&#xff09;是一个可用区是一个或多个物理数据中心的集合&#xff0c;有独立的风火水电&#xff0c;可用区内逻辑上再将计算、网络、存储等资源划分成多个集群。一个地域中的多个可用区间通过高速光纤相连&#xff0c;以满足…

Ubuntu安装Mininet和Ryu出现的问题

问题1-Ryu: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host‘pypi.org’, port443): 解决&#xff1a; pip install XXX -i http://pypi.douban.com/simple --trusted-host pypi.douban.com或 pip install XXX -i http://mirrors.aliyun.c…

国内首个BIM全生命周期装配式建筑项目,建设仅用25周

hi大家好&#xff0c;这里是建模助手。 文章开头我想先问问各位&#xff0c;在你眼中&#xff0c;25周能干点什么&#xff01;小编和你说&#xff0c;在建筑行业里的25周&#xff0c;可以完成一整个保障房项目的建设。 我没开玩笑... 4月16日下午&#xff0c;随着最后一个混凝土…

信号与槽机制

一、信号与槽 1、什么是信号与槽&#xff1f; 信号和槽是用于对象之间的通信&#xff0c;它是Qt的核心机制&#xff0c;在Qt编程中有着广泛的应用。如果想学好Qt&#xff0c;一定要充分掌握信号的槽的概念与使用。 2、信号和槽的代码实例 在Qt中&#xff0c;发送对象、发送的信…

美国纽扣电池的包装电池盒必须附带警告标签16 CFR 第 1700.20

美国纽扣电池及硬币电池的包装、电池盒必须附带警告标签16 CFR 第 1700.20 美国要求在纽扣电池或硬币电池的包装上、电池盒上以及包含纽扣电池或硬币电池的消费品附带说明和手册上贴上警告标签。 商品法规、标准和要求纽扣电池和硬币电池以下所有项&#xff1a; 16 CFR 第 17…

虚幻引擎配置物体水面浮力的简便方法

虚幻引擎配置物体水面浮力的简便方法 目录 虚幻引擎配置物体水面浮力的简便方法前言前期工作配置水面浮力针对一个立方体的水面浮力配置针对船3D模型的水面浮力配置 小结 前言 在使用虚幻引擎配置导入的3D模型时&#xff0c;如何快速地将水面浮力配置正确&#xff0c;从而使得…

快速原型设计工具(Axure)的简单使用

1.运行 安装好后运行&#xff0c;可以看到欢迎界面(不想每次启动都弹出这个的话建议勾选启动时不显示) ​ 这就是Axure的主要界面了&#xff0c;能成功进到这里就说明安装成功&#xff01; 2.Axure主要界面 3.展示形式 通过Axure这个软件生成和打开的文件的后缀名是 .rp&#x…

如何在Jetpack Compose中将可滚动项捕捉到屏幕中心

如何在Jetpack Compose中将可滚动项捕捉到屏幕中心 从 Snapper 迁移到 SnapFlingBehavior 之前&#xff0c;我们探讨了Android应用程序开发中一个常见的用例&#xff1a;在fling手势后将可滚动项捕捉到屏幕中心。 为了在Jetpack Compose中实现这一目标&#xff0c;我们使用…

手把手教你写Web自动化测试并生成美观交互的测试报告

B站首推&#xff01;2023最详细自动化测试合集&#xff0c;小白皆可掌握&#xff0c;让测试变得简单、快捷、可靠https://www.bilibili.com/video/BV1ua4y1V7Db 目录 摘要&#xff1a; Web自动化测试 Allure测试报告 总结 摘要&#xff1a; 在Web应用程序开发中&#xff0c…

ICV: 全球QRNG产业规模在2030年有望突破200亿美元

近日&#xff0c;专注于前沿科技领域的国际咨询机构ICV发布了《全球量子随机数发生器的产业研究报告》&#xff0c;从多个角度对QRNG的市场进行预测。 QRNG 是解决与随机数相关的问题&#xff08;例如密码解决方案&#xff09;的重要硬件来源。 QRNG 是随着量子物理技术的发展…

DJ4-4 基本分页存储管理方式

目录 离散分配的基本概念 4.4.1 分页存储管理基本思想 1、分页存储管理的基本方法 2、页面与物理块 3、实现分页存储管理的数据结构 4、实现分页存储管理的地址结构 5、分页存储管理的逻辑地址表示 4.4.2 地址变换机构 1、基本的地址变换机构 2、具有快表的地址变换…

Alibaba技术官熬夜肝出的,Kafka “限量笔记” 牛掰 ~

前言 分布式&#xff0c;是程序员必备技能之一&#xff0c;在面试过程中属于必备类的&#xff0c;在工作中更是会经常用到。而Kafka是一个分布式的基于发布订阅的消息队列&#xff0c;目前它的魅力是无穷的&#xff0c;对于Kafka的奥秘&#xff0c;还需要我们细细去探寻。 要…

GUN C编译器拓展语法学习笔记(三)内联函数、内建函数与可变参数宏

内联函数、内建函数与可变参数宏 一、内联函数1.1 属性声明&#xff1a;noinline1.2 内联函数与宏1.3 编译器对内联函数的处理1.4 内联函数为什么定义在头文件中 二、内建函数2.1 内建函数定义2.2 常用的内建函数2.3 C标准库的内建函数2.4 内建函数&#xff1a;__builtin_const…