笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述Java基础之细说枚举相关的知识,希望能为你提供帮助。
枚举类(Enum)当我们使用关键字 ??enum?
? 创建一个枚举时,他具有如下特性
特点
- 构造器是私有的
- 是一个类,默认继承?
?Enum?
??,并且使用??final?
? 修饰,可以有自己的成员变量,成员方法,静态方法、静态变量等
无参数的枚举
enumHTTP_STATUS
OK,//是一个HTTP_STATUS枚举类型
NOT_FOUND
编译后的代码
enum HTTP_STATUS
OK,
NOT_FOUND;
//默认生成私有无参构造器
private HTTP_STATUS()
有参数的枚举
enumHTTP_STATUS
OK(200,"请求成功"),
NOT_FOUND(404,"无法找到资源");
private Integer code;
private String value;
private HTTP_STATUS(int code, String value)
this.code = code;
this.value = https://www.songbingjia.com/android/value;
public Integer getCode()
return code;
public String getValue()
return value;
查看字节码
Classfile /D:/question/questions/target/classes/com/tq/questions/HTTP_STATUS.class
Last modified 2022-6-25; size 1758 bytes
MD5 checksum f38e7c76916dd6c0f40f3c055dbf8e19
Compiled from "Test.java"
//继承Enum,final修饰
final class com.tq.questions.HTTP_STATUS extends java.lang.Enum< com.tq.questions.HTTP_STATUS>
minor version: 0
major version: 52
flags: ACC_FINAL, ACC_SUPER, ACC_ENUM
...........
//每一个枚举类型都是static final 修饰的
public static final com.tq.questions.HTTP_STATUS OK;
descriptor: Lcom/tq/questions/HTTP_STATUS;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
public static final com.tq.questions.HTTP_STATUS NOT_FOUND;
descriptor: Lcom/tq/questions/HTTP_STATUS;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
public static com.tq.questions.HTTP_STATUS[] values();
descriptor: ()[Lcom/tq/questions/HTTP_STATUS;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: getstatic#1// Field $VALUES:[Lcom/tq/questions/HTTP_STATUS;
3: invokevirtual #2// Method "[Lcom/tq/questions/HTTP_STATUS; ".clone:()Ljava/lang/Object;
6: checkcast#3// class "[Lcom/tq/questions/HTTP_STATUS; "
9: areturn
LineNumberTable:
line 20: 0
public static com.tq.questions.HTTP_STATUS valueOf(java.lang.String);
descriptor: (Ljava/lang/String; )Lcom/tq/questions/HTTP_STATUS;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: ldc#4// class com/tq/questions/HTTP_STATUS
2: aload_0
3: invokestatic#5// Method java/lang/Enum.valueOf:(Ljava/lang/Class; Ljava/lang/String; )Ljava/lang/Enum;
6: checkcast#4// class com/tq/questions/HTTP_STATUS
9: areturn
LineNumberTable:
line 20: 0
LocalVariableTable:
StartLengthSlotNameSignature
0100nameLjava/lang/String;
public java.lang.Integer getCode();
descriptor: ()Ljava/lang/Integer;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield#8// Field code:Ljava/lang/Integer;
4: areturn
LineNumberTable:
line 34: 0
LocalVariableTable:
StartLengthSlotNameSignature
050thisLcom/tq/questions/HTTP_STATUS;
public java.lang.String getValue();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield#9// Field value:Ljava/lang/String;
4: areturn
LineNumberTable:
line 38: 0
LocalVariableTable:
StartLengthSlotNameSignature
050thisLcom/tq/questions/HTTP_STATUS;
static ;
descriptor: ()V
flags: ACC_STATIC
Code:
stack=7, locals=0, args_size=0
0: new#4// class com/tq/questions/HTTP_STATUS
3: dup
4: ldc#11// String OK
6: iconst_0
7: sipush200
10: ldc#12// String 请求成功
12: ldc#13// String
14: invokespecial #14// Method "< init> ":(Ljava/lang/String; IILjava/lang/String; Ljava/lang/String; )V
17: putstatic#15// Field OK:Lcom/tq/questions/HTTP_STATUS;
20: new#4// class com/tq/questions/HTTP_STATUS
23: dup
24: ldc#16// String NOT_FOUND
26: iconst_1
27: sipush404
30: ldc#17// String 无法找到资源
32: ldc#13// String
34: invokespecial #14// Method "< init> ":(Ljava/lang/String; IILjava/lang/String; Ljava/lang/String; )V
37: putstatic#18// Field NOT_FOUND:Lcom/tq/questions/HTTP_STATUS;
40: iconst_2
41: anewarray#4// class com/tq/questions/HTTP_STATUS
44: dup
45: iconst_0
46: getstatic#15// Field OK:Lcom/tq/questions/HTTP_STATUS;
49: aastore
50: dup
51: iconst_1
52: getstatic#18// Field NOT_FOUND:Lcom/tq/questions/HTTP_STATUS;
55: aastore
56: putstatic#1// Field $VALUES:[Lcom/tq/questions/HTTP_STATUS;
59: return
LineNumberTable:
line 4: 0
line 5: 20
line 3: 40
通过汇编指令,发现了枚举类型除了我们自己定义的方法外,还有如下方法
//获取所有的枚举类型
HTTP_STATUS[] values()
//根据枚举名称获取对应的枚举类型
HTTP_STATUS valueOf(java.lang.String);
此外,默认是继承了 Enum 类型,并且用 final 修饰
public abstract class Enum< E extends Enum< E> > implements Comparable< E> , Serializable
.................
/**
* prevent default deserialization
* 反序列化直接抛异常
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException
throw new InvalidObjectException("cant deserialize enum");
private void readObjectNoData() throws ObjectStreamException
throw new InvalidObjectException("cant deserialize enum");
/**
* Throws CloneNotSupportedException.This guarantees that enums
* are never cloned, which is necessary to preserve their "singleton"
* status.
*
* @return (never returns)
*/
protected final Object clone() throws CloneNotSupportedException
throw new CloneNotSupportedException();
枚举类型的成员变量是 ?
为什么说枚举创建单例是安全的
?static final?
? 修饰的,在类加载阶段就已经被被赋值了,而类加载阶段是线程安全的现在我们想一个办法创建一个对象来破环枚举单例,我们知道的有如下方法
- Java关键字new,但是枚举类型的构造器是私有的(?
?private?
?) - 通过反射,但是反射也是依赖于构造器
- 反序列化,因为枚举类型继承了Enum,但是Enum的?
?readObject?
? 方法直接抛异常 - 通过 clone 方法,因为枚举类型继承了Enum,但是Enum的?
?clone?
?? 方法被??final?
? 修饰 ,而且方法直接抛异常
【Java基础之细说枚举】
推荐阅读
- 视觉项目day28.21号实验记录(手机固定高度15cm拍摄+直方图均衡化+模板匹配,模板12个,测试28个,效果十分差)
- React 简书项目实战icon优化header
- css裁剪图片 clip-path
- 研究生数学建模竞赛-无人机在抢险救灾中的优化应用
- Java基础 (算术,赋值,逻辑,位,三元 运算符)
- 抖音__ac_signature
- 图像分割——基于二维灰度直方图的阈值处理
- 力扣——求一组字符中的第一个回文字符
- Nacos2.0 配置中心管理,动态配置更新