在运行时反射性地构建枚举 - 高度可疑机构

主要观点:不应在运行时添加枚举值,介绍了多种在 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 崩溃。
阅读 69
0 条评论