枚举的使用

背景以及定义

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

public static final int RED = 1;

public static final int GREEN = 2;

public static final int BLUE = 3;

但是常量举例有不好的地方,例如:可能碰巧有一个数字1,但是他有可能误会为是RED,现在我们可以直接用枚举来进行组织,这样一来,就拥有了类型,枚举类型.而不是普通的整型1.

public enum TestEnum {

        RED, GREEN, BLUE;

}

优点:将常量组织起来统一进行管理

场景:错误状态码,消息类型,颜色的划分,状态基等...

本质:这个是java.lang.Enum的子类,也就是说,自己写的枚举类,就算没有显示的继承Enum,但是其默认继承了这个类.

使用

switch语句

public enum TestEnum {RED, BLACK,GREEN,WHITE;public static void main(String[] args) {TestEnum testEnum = TestEnum.BLACK;switch (testEnum) {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("green");break;default:break;}}
}

执行结果:
 

2.常用方法:

 Enum类常用的方法

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

示例1:

public enum TestEnum1 {RED, BLACK, GREEN, WHITE;public static void main(String[] args) {TestEnum1[] testEnum1s = TestEnum1.values();for(int i = 0; i < testEnum1s.length; i++) {System.out.println(testEnum1s[i] + " " + testEnum1s[i].ordinal());}System.out.println("======================");System.out.println(TestEnum1.valueOf("GREEN"));}
}

示例2:

public enum TestEnum2 {RED, BLACK, GREEN, WHITE;public static void main(String[] args) {//拿到枚举实例BLACKTestEnum2 testEnum2 = TestEnum2.BLACK;//拿到枚举实例REDTestEnum2 testEnum21 = TestEnum2.RED;System.out.println(testEnum2.compareTo(testEnum21));System.out.println(BLACK.compareTo(RED));}
}

刚刚说过,在Java当中枚举实际上就是一个类.所以我们在定义枚举的时候,还可以这样使用定义和枚举.

重要:枚举的构造方法默认是私有的

public enum TestEnum3 {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 TestEnum3(String name, int key) {this.name = name;this.key = key;}public static TestEnum3 getEnumKey(int key) {for(TestEnum3 t : TestEnum3.values()) {if(t.key == key) {return t;}}return null;}public static void main(String[] args) {System.out.println(getEnumKey(2));}
}

枚举优点缺点

优点:

1.枚举常量更简单更安全

2.枚举具有内置方法,代码更优雅

缺点:

1.不可继承,无法扩展

 枚举和反射

枚举是否能通过反射,拿到实例对象呢?

我们知道,在反射中,任何的一个类,哪怕是私有的,我们也可以通过反射拿到它的实例对象,那么枚举的构造方法也是私有的,我们是否可以拿到呢?接下来,我们来试验一下.

同样利用上述提供的枚举类来进行举例:

import java.lang.reflect.Constructor;public enum TestEnum3 {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 TestEnum3(String name, int key) {this.name = name;this.key = key;}public static TestEnum3 getEnumKey(int key) {for(TestEnum3 t : TestEnum3.values()) {if(t.key == key) {return t;}}return null;}public static void reflectPrivateConstructor() {try {Class<?> classStudent = Class.forName("demo5.TestEnum3");//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类时提供了两个参数分别是String和intConstructor<?> declaredConstructorStudent = classStudent.getDeclaredConstructor(String.class, int.class);//设置为true后可以修改访问权限declaredConstructorStudent.setAccessible(true);Object objectStudent = declaredConstructorStudent.newInstance("绿色", 666);TestEnum3 testEnum3 = (TestEnum3) objectStudent;System.out.println("获取枚举的私有构造函数" + testEnum3);} catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) {reflectPrivateConstructor();}
}

 输出结果:

上述异常信息是:java.lang.NoSuchMethodException:TestEnum.<init>(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("demo5.TestEnum3");//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类时提供了两个参数分别是String和intConstructor<?> declaredConstructorStudent = classStudent.getDeclaredConstructor(String.class, int.class, String.class, int.class);//设置为true后可以修改访问权限declaredConstructorStudent.setAccessible(true);//前两个是父类参数,后面两个是子类参数Object objectStudent = declaredConstructorStudent.newInstance("父类参数", 666, "子类参数", 888);TestEnum3 testEnum3 = (TestEnum3) objectStudent;System.out.println("获取枚举的私有构造函数" + testEnum3);} catch(Exception e) {e.printStackTrace();}}

此时的运行结果是:

 

他还是报错了.不过这正是我们想要的结果!此时的异常信息显示,是我的一个方法,这个方法是:

newInstance()报错了!没错,问题就是在这里,我们来看一下这个方法的源码,为什么会抛出

java.lang.IllegalArgumentException异常呢>? 

源码显示:

 

是的,枚举在这里被过滤了,你不能通过反射获取枚举类的实例! 

因此,枚举对象是非常安全的,就算通过反射,也是不可以创建一个枚举对象的. 

总结

1.枚举本身就是一个类,其构造方法默认是私有的,且都是继承于java.lang.Enum

2.枚举可以避免反射和序列化问题

3.枚举的优点(简单安全,有内置方法,代码更优雅)与缺点(无法拓展)

面试问题

1.写一个单例模式

class Singleton {private static Object locker = new Object();private static volatile Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if(instance == null) {synchronized (locker) {if(instance == null) {instance = new Singleton();}}}return instance;}
}

2.用枚举实现一个单例模式

public enum TestEnum4 {INSTANCE;public TestEnum4 getInstance() {return INSTANCE;}public static void main(String[] args) {TestEnum4 singleton1 = TestEnum4.INSTANCE;TestEnum4 singleton2 = TestEnum4.INSTANCE;System.out.println("两个实例是否相同: " + (singleton1 == singleton2));}
}

 

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

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

相关文章

Leetcode 2972. Count the Number of Incremovable Subarrays II

Leetcode 2972. Count the Number of Incremovable Subarrays II 1. 解题思路2. 代码实现 题目链接:2972. Count the Number of Incremovable Subarrays II 1. 解题思路 这道题需要注意的是&#xff0c;题目要求只能删除一个连续子串&#xff0c;使得剩余的元素变成一个递增…

【Vue3】Vue3使用video-player实现视频播放

一、video-player 介绍 video-player 是一个基于 video.js 的视频播放器组件&#xff0c;它提供了丰富的功能&#xff0c;包括视频播放、暂停、快进、快退、全屏、音量控制等。 video-player 的使用非常简单&#xff0c;如下安装即可。 npm install video.js videojs-player…

【数值分析】反幂法,matlab实现

反幂法20231226 一种求实矩阵 A {A} A 的按模最小的特征值&#xff0c;及其对应的特征向量 x i {x_i} xi​ 的方法&#xff0c;只能求一个。 要保证矩阵最小特征值只有一个&#xff0c;有 n {n} n 个线性无关的特征向量&#xff0c;矩阵可逆。 可以通过求矩阵 A − 1 {A^{…

【Web API系列】使用getDisplayMedia来实现录屏功能

文章目录 前言一、认识getD该处使用的url网络请求的数据。二、使用步骤1.使用方法一实现录屏2.使用方法二实现录屏3. 运行效果 延伸 前言 Web API经过长期的发展&#xff0c;尤其是最近&#xff0c;发展相当迅猛&#xff0c;现在已经支持很多功能了&#xff0c;一些原生就支持…

[Linux]——彻底学通权限

学习权限 一、权限概念二、权限管理2.1文件访问者分类&#xff08;人&#xff09;2.2文件类型和访问权限&#xff08;事物的属性&#xff09;2.3 文件访问权限的相关设置方法 三、目录的权限3.1、进入目录的权限3.2、粘滞位 四、关于权限的总结 一、权限概念 Linux下有两种用户…

【AI】Langchain-Chatchat搭建本地知识库-未完,先记录踩的坑

事先说一下&#xff0c;我本地的显卡4070只有12G显存&#xff0c;无法运行本地知识库&#xff0c;我把自己折腾的过程和遇到的坑先记录一下吧&#xff0c;后续如果有算力的话就再跑一遍试试。后续来了&#xff1a;【AI】使用阿里云免费服务器搭建Langchain-Chatchat本地知识库 …

阿赵UE学习笔记——4、新建关卡

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   之前介绍了虚幻引擎的常用窗口功能&#xff0c;这次开始创建游戏内的世界了。首先先从创建关卡开始。 一、创建新关卡 在使用UE引擎制作游戏&#xff0c;首先要有一个场景作为基础&#xff0c;这个场景在UE里面成为关卡。…

PHP面向对象基础之类、对象和基本特点

类就是同一类事物的划分&#xff0c;比如车&#xff0c;当然车还可以划分其他类&#xff0c;比如小轿车、大卡车等。通俗点&#xff0c;类就是指由变量和作用于变量的函数组成的集合。 对象是类的一个实例&#xff0c;比如车牌固定的一辆车。 面向对象编程的三个特点&#xff1…

带你认识 WIDGET、WINDOW 、FRAME和 FRAMEGROUP

1、概述 在 YonBuilder 移动开发中&#xff0c;开发者需要了解一些常用的概念术语&#xff0c;其中和App整体框架结构及页面层级组成相关最重要几个重要概念&#xff0c;就是 Widget、 Window 和 Frame、frameGroup。掌握了这几个概念&#xff0c;对于开发者开发 App 时的 API…

docker container 指定gpu设备

1&#xff0c; 在yaml中 Turn on GPU access with Docker Compose | Docker Docs Example of a Compose file for running a service with access to 1 GPU device: services:test:image: nvidia/cuda:12.3.1-base-ubuntu20.04command: nvidia-smideploy:resources:reserva…

linux离线安装jdk11

1. 下载java11&#xff0c;Java Downloads | Oracle 2. 文件安装 jdk11&#xff1a; mkdir /usr/lib/jvm/ 将下载的文件&#xff0c;解压到/usr/lib/jvm/下 tar -zxf jdk-11.0.21_linux-x64_bin.tar.gz -C /usr/lib/jvm/ 3. 将以下命令写入bashrc文件 export JAVA_HOME/us…

ARAM 中断实验

思路&#xff1a;按键->EXTI->GIC->CPU->异常向量表 //使能GPIOF时钟 //设置PF9管脚为输入(KEY1) //设置PF9作为EXTI9事件的输入(事件编号对应管脚号) //设置下降沿使能检测EXTI9事件 (也可设置上升沿没有下降沿严谨方便,不同场景不同选择) //设置EXTI9事件不…

26、湾湾国立阳明交通大学、湾湾长庚纪念医院提出:ALL Attention U-Net,独属头部CT分割的[玛格丽特]

本文由台湾国立阳明交通大学、台湾长庚纪念医院于2023年12月16日在arXiv<Image and Video Processing>发表。 论文地址&#xff1a; 2312.10483.pdf (arxiv.org) 0、Abstract 脑出血在 Head CT扫描中作为第一线工具&#xff0c;帮助专家诊断不同类型的出血。然而&…

云端的DevOps之旅:深入了解AWS Code系列工具

对于开发者和IT专业人员来说&#xff0c;理解这些工具如何帮助我们从代码编写、编译、测试到部署的完整流程将极其重要。今天&#xff0c;我将详细介绍 AWS CodeCommit, CodeBuild, CodeDeploy, 和CodePipeline 这一系列以“Code”命名的开发和部署工具 AWS CodeCommit&#x…

Tomcat面试题(10道含答案),由浅入深

请解释Tomcat的基本概念和作用 Tomcat是一个开源的Java Web服务器和Servlet容器&#xff0c;用于提供基于Java的应用程序运行环境。它支持Java Servlet规范&#xff0c;使得开发者能够快速构建和部署基于Web的应用程序。 请描述Tomcat的目录结构&#xff0c;并解释各个目录的…

cmd启动Java项目提示:jar中没有主清单属性

1、问题 2、原因 在IDEA中开发SpringBoot项目并打成jar包&#xff0c; 需要添加springboot打包插件&#xff0c;如果不添加&#xff0c;仅仅用maven进行打包&#xff0c;打成包里面是少文件的。 <build><plugins><!--springboot打包插件--><plugin>&…

ElasticSearch之RestClient笔记

1. ElasticSearch 1.1 倒排索引 1.2 ElasticSearch和Mysql对比 1.3 RestClient操作 导入依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.15.…

枚举(蓝桥杯备赛系列)acwing版

枚举 前言 hello&#xff0c;大家好&#xff0c;前面一段时间已经是把acwing Linux基础课讲完了&#xff0c;其实那些内容完全可以带领小白入门Linux我说过如果有人留言要Linux和Windows server 配置DNS Web ftp 的内容我就做一期&#xff0c;但是没人留言我也就先不自作多情了…

【HeyGen】让照片开口说话 —— 登录和使用:详细指南!

【HeyGen】让照片开口说话 关于HeyGen登录HeyGenStep1. 点击”免费开始使用“Step2. 账号注册Step3. 再次点击”Get Started“Step4. 常规个人信息调查Step5. 登录成功 使用HeyGenStep1. 上传Avatar&#xff08;头像&#xff09;Step2. 选定Avatar&#xff08;头像&#xff09;…

漏洞复现-泛微OA xmlrpcServlet接口任意文件读取漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…