枚举的使用

背景以及定义

枚举是在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,一经查实,立即删除!

相关文章

【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里面成为关卡。…

带你认识 WIDGET、WINDOW 、FRAME和 FRAMEGROUP

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

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…

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;帮助专家诊断不同类型的出血。然而&…

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;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

Java基础回顾——JDBC

文章目录 介绍使用JDBC事务JDBC BatchJDBC连接池 介绍 Java为关系数据库定义了一套标准的访问接口&#xff1a;JDBC&#xff08;Java Database Connectivity&#xff09; JDBC是Java程序访问数据库的标准接口 好处&#xff1a; 各数据库厂商使用相同的接口&#xff0c;Java…

【DevOps 工具链】搭建 项目管理软件 禅道

文章目录 1、简介2、环境要求3、搭建部署环境3.1. 安装Apache服务3.2. 安装PHP环境&#xff08;以php7.0为例 &#xff09;3.3. 安装MySQL服务 4、搭建禅道4.1、下载解压4.2、 配置4.2.1、 启动4.2.2、自启动4.2.3、确认是否开机启动 5、成功安装 1、简介 禅道是国产开源项目管…

Java——基本数据类型

Java基本数据类型 一、 整型1. byte2. short3. int4. long 二、浮点型1. float2. double 三、 字符型(char)四、 布尔型&#xff08;boolean&#xff09; 总结 算下刚转Java到现在也有三个多月了&#xff0c;所以打算对Java的知识进行汇总一下&#xff0c;本篇文章介绍一下Java…

Vue实现响应式布局

前提准备&#xff1a;响应式布局有两种方法&#xff0c;看自己想要哪种。 方法一&#xff1a;百分比 用百分比去写元素的宽度&#xff0c;然后让子元素撑起父元素的高度 .parent {width: 50%; }.child {width:100%;height:100px; } 方法二&#xff1a;vh、vw vw、vh是基于视…

Git一个仓库包含多个不同的项目VUE(老项目的基础上,新建分支放新项目)

背景&#xff1a; 原有项目A&#xff08;vue2.6&#xff09;&#xff0c;需要在A的基础上接入组件库&#xff0c;涉及到项目升级&#xff0c;领导不想走这条路&#xff0c;建议重新构建一版2.7的项目B&#xff0c;那么现在就需要把项目B与项目A远程到同一个仓库&#xff1b; 解…

网络通信-Linux 对网络通信的实现

Linux 网络 IO 模型 同步和异步&#xff0c;阻塞和非阻塞 同步和异步 关注的是调用方是否主动获取结果 同步:同步的意思就是调用方需要主动等待结果的返回 异步:异步的意思就是不需要主动等待结果的返回&#xff0c;而是通过其他手段比如&#xff0c;状态通知&#xff0…

TP-LINK AC1200 双频无线路由器网段设置

TP-LINK AC1200 双频无线路由器网段设置 1. 管理页面2. 上网设置3. 无线设置4. LAN 口设置 原始 3 网段5. LAN 口设置 设置 1 网段6. DHCP 服务器7. 重新连接References ​ 1. 管理页面 管理页面&#xff1a;http://tplogin.cn/ 上网方式&#xff1a;自动获得 IP 地址 2. 上网…