主要观点:不应在运行时添加枚举值,介绍了多种在 Java 中处理枚举的方法及相关问题,包括反射创建枚举对象、修改枚举相关字段等,还提及不同 Java 版本中的变化及一些奇特现象。
关键信息:
- 枚举的目的是持有固定的编译时常量,
EnumMap有特定优势,不应随意在运行时添加枚举值。 - 在 Java 8 及之前,可通过反射等方式创建枚举对象,但会有警告且可能导致 JIT 错误。
- 可通过反射修改
$VALUES数组,但要小心 JVM 对private static final字段的处理,否则可能导致编译错误或 JIT 优化失效。 - Java 21 中,
Reflection.fieldFilterMap对反射进行了更强的封装,某些反射操作变得更困难。
重要细节:
- Java 中的枚举类有特定的结构和方法,如
values()、valueOf()等。 - 通过反射获取构造函数并创建枚举对象时,会遇到
IllegalArgumentException。 - 可通过修改字段修饰符来绕过
private final限制,但可能导致 JIT 优化问题。 - 可使用 ASM 库解析类并修改字段修饰符,或使用特殊的类加载器来处理枚举相关操作。
- 在 Java 21 中,某些反射操作因
fieldFilterMap的限制而变得困难,如获取Constructor等。 - 枚举类的字段名不一定是
$VALUES,可能会有特殊情况导致名称变化。如果创建过多带有特殊名称的字段,可能导致 javac 崩溃。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。