主要观点:不应在运行时添加枚举值,介绍了多种在 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) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。