• JAVA代码
public enum EnumTest {
HELLO,WORLD
}
  • 字节码
public final class EnumTest extends java.lang.Enum<EnumTest> {
public static final EnumTest HELLO; public static final EnumTest WORLD; public static EnumTest[] values();
Code:
0: getstatic #1 // Field $VALUES:[LEnumTest;
3: invokevirtual #2 // Method "[LEnumTest;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[LEnumTest;"
9: areturn // 从当前方法返回对象引用 // 调用了(EnumTest)java.lang.Enum.valueOf(EnumTest.class,String)
public static EnumTest valueOf(java.lang.String);
Code:
0: ldc #4 // class EnumTest
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 // class EnumTest
9: areturn static {};
Code:
0: new #4 // class EnumTest
3: dup
4: ldc #7 // String HELLO
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field HELLO:LEnumTest;
13: new #4 // class EnumTest
16: dup
17: ldc #10 // String WORLD
19: iconst_1
20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
23: putstatic #11 // Field WORLD:LEnumTest;
26: iconst_2
27: anewarray #4 // class EnumTest, 创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶
30: dup
31: iconst_0
32: getstatic #9 // Field HELLO:LEnumTest;获取指定类的静态域,并将其值压入栈顶
35: aastore
36: dup
37: iconst_1
38: getstatic #11 // Field WORLD:LEnumTest;
41: aastore
42: putstatic #1 // Field $VALUES:[LEnumTest;用栈顶的值为指定的类的静态域赋值
45: return
}
  • 参考源码实现的枚举(没有继承 java.lang.Enum):
public final class MyEnum {
private final String s; private MyEnum(String s) {
this.s = s;
} public static final MyEnum HELLO = new MyEnum("HELLO");
public static final MyEnum WORLD = new MyEnum("WORLD"); private static volatile MyEnum[] $VALUES; static {
Field[] fields = MyEnum.class.getFields();
List<Field> list = Arrays.asList(fields);
$VALUES = list.stream().map(field -> {
try {
return field.get(MyEnum.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}).collect(Collectors.toList()).toArray(new MyEnum[fields.length]);
} public static MyEnum[] values() {
return $VALUES;
} public static MyEnum valueOf(String name) throws NoSuchFieldException, IllegalAccessException {
Class<MyEnum> clazz = MyEnum.class;
Field field = clazz.getField(name);
return (MyEnum) field.get(clazz);
} @Override
public String toString() {
return s;
}
}
  • java.lang.Enum类
// Enum 不能直接被继承
// 下列省略部分代码
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable { private final String name; private final int ordinal; public final String name() {
return name;
} public final int ordinal() {
return ordinal;
} protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
} public String toString() {
return name;
} // 比较ordinal值,用于排序
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
} @SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass(); // 获取当前类的Class
Class<?> zuper = clazz.getSuperclass(); // 获取当前类的父类
// 如果父类是Enum.class,则返回当前类的Class,否则返回父类的Class
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
} public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null) return result;
// 为什么不先判断name是否等于null?
if (name == null) throw new NullPointerException("Name is null");
throw new IllegalArgumentException("No enum constant " + enumType.getCanonicalName() + "." + name);
} public final boolean equals(Object var1) {
return this == var1;
}
} public final class Class<T>{ private transient volatile Map<String, T> enumConstantDirectory; // 简单的说生成枚举Map:{"HEELO":EnumTest.HELLO,"WORLD":EnumTest.WORLD}
Map<String, T> enumConstantDirectory() {
Map<String, T> directory = enumConstantDirectory;
if (directory == null) {
T[] universe = getEnumConstantsShared();
if (universe == null)
throw new IllegalArgumentException(getName() + " is not an enum type");
directory = new HashMap<>(2 * universe.length);
for (T constant : universe) {
directory.put(((Enum<?>)constant).name(), constant);
}
enumConstantDirectory = directory;
}
return directory;
} private transient volatile T[] enumConstants; T[] getEnumConstantsShared() {
T[] constants = enumConstants;
if (constants == null) {
// 非Enum 直接返回null
if (!isEnum()) return null;
try {
final Method values = getMethod("values");
// 提升访问修饰
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public Void run() {
values.setAccessible(true);
return null;
}
});
// 反射调用values方法,得到枚举数组
@SuppressWarnings("unchecked")
T[] temporaryConstants = (T[])values.invoke(null);
enumConstants = constants = temporaryConstants;
}catch (InvocationTargetException | NoSuchMethodException |IllegalAccessException ex) {
return null;
}
}
return constants;
} public boolean isEnum() {
// 返回此类或接口以整数编码的 Java语言修饰符,如:public private protected、enum等。
// 如果modifers有enum修饰语ENUM &操作将得到ENUM,不等于0。
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
}
  • 测试
Class<?> aClass = EnumTest.HELLO.getClass();
System.out.println(aClass); // class EnumTest
System.out.println(aClass.getSuperclass()); // class java.lang.Enum
  • 结论

    • 枚举类是一个普通的java类,enum类型只是java的语法糖,编译器帮助开发人员转化为Eunm类。
    • 枚举类继承了java.lang.Enum类,valueOf和values方法继承自Enum类。
    • java.lang.Enum类不能被直接继承,所以自己实现的valueOf的实现采用了反射获取字段。
    • java.lang.Enum类的valueOf实现采用了Class类反射和内部的map缓存。

作业16:java枚举类的秘密的更多相关文章

  1. Java枚举类在生产环境中的使用方式

    前言   Java枚举在项目中使用非常普遍,许多人在做项目时,一定会遇到要维护某些业务场景状态的时候,往往会定义一个常量类,然后添加业务场景相关的状态常量.但实际上,生产环境的项目中业务状态的定义大部 ...

  2. Java基础15:深入剖析Java枚举类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  3. Java枚举类使用和总结

    1.枚举类使用情况一: package com.bie.util; import java.util.HashMap; import java.util.Map; /** * * @author bi ...

  4. Java 枚举类 详解

    1.枚举是什么? Java中的枚举其实是一种语法糖,在 JDK 1.5之后出现,用来表示固定且有限个的对象.比如一个季节类有春.夏.秋.冬四个对象:一个星期有星期一到星期日七个对象.这些明显都是固定的 ...

  5. 夯实Java基础系列14:深入理解Java枚举类

    目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...

  6. Java枚举类、注解和反射

    本文主要介绍的是枚举类,注解和反射.还有一些基础知识:static,基本数据类型,运算符优先级放在文中,以便查阅复习. 其中牵扯到泛型的部分,可参考本人的另一篇博客:(Collection, List ...

  7. Java枚举类与注解详解——一篇文章读懂枚举类与注解详

    目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代码的 ...

  8. Java 枚举类

    如果要定义一个枚举类: public enum Size { SAMLL, MEDIUM, LARGE, EXTRA, EXTRA_LARGE}; 实际上,这个声明定义的类型是一个类,它刚好有4个实例 ...

  9. java 枚举类 enum 总结

    枚举定义: enum是计算机编程语言中的一种数据类型.枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等.如果把这些量 ...

随机推荐

  1. Map接口和Collection接口的区别

    * Map是双列的,Collection是单列的 * Map的键唯一,Collection的子体系Set是唯一的 * Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针 ...

  2. 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_17-课程预览功能开发-前后端测试

    启动前端代码 前端课程找到课程的发布页面 这样就打开了预览页面 结束

  3. Fakes里的stub和shim的区别

    stub常用于虚拟接口.类.方法,无法重写静态方法(stub需要传递到具体调用代码中) shim常用于重写静态方法(在ShimsContext.Create()作用域内,拦截Runtime动态修改方法 ...

  4. Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】

    1.环境说明: 系统版本:Ubuntu 14.04 LVS1物理IP:14.17.64.2   初始接管VIP:14.17.64.13 LVS2物理IP:14.17.64.3   初始接管VIP:14 ...

  5. 在Win7环境下搭建Geant4工作平台

    本物理专业小硕,现在材料实验室工作,研究方向大概是核屏蔽材料的软件模拟吧.其实实验室里大多数师兄弟都是搞焊接的,平时能接触到这类直接给源码自己编译的软件的机会基本为零,所以一切都靠自己探索,成功搭建了 ...

  6. Unity与Android刘海屏适配

    本周学习Unity与Android刘海屏适配 关于刘海屏适配部分 网上有很多教程 这里只是做一下整理 https://blog.csdn.net/xj1009420846/article/detail ...

  7. Echarts 图表的本地配置

    前言 Echarts是一个美观的可视化工具,但是很多朋友初次接触,不知道自己该怎么创建一个包含Echartst图表的本地HTML网页,本文将详细地介绍Echarts的使用流程. 使用流程步骤 共分为三 ...

  8. OpenGL学习笔记 之一 (基本的图形绘制)

    参考网址:http://www.cnblogs.com/FredCong/archive/2012/10/13/2722893.html #include <glut.h> #includ ...

  9. (1) laravel php artisan list make

    php artisan list make Laravel Framework 5.4.36 Usage: command [options] [arguments] Options: -h, --h ...

  10. web前端常用meta整理

    标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务. 页面关键词 <meta ...