我可以从Java类文件中删除枚举值吗?

我可以从Java类文件中删除枚举值吗?,java,enums,bytecode,bytecode-manipulation,Java,Enums,Bytecode,Bytecode Manipulation,假设我有一个较大的Java应用程序的jar文件,但无法从源代码重新生成。我们还可以规定,我希望通过消除导致该行为的枚举值来修改应用程序不良行为的一个方面。我是否可以从相应的.class文件中删除枚举的一个值,重新创建它所属的jar,并实现一个功能仍然正常的应用程序的目标?实现这一目标的方法是什么?可能的缺点是什么 只需要使用JDK中可用的工具的答案比需要额外的工具(如中列出的工具)更好。如果它有答案,这将是有用的 对应用程序进行更改以执行反射、动态字节码操作或对枚举值进行运行时修改都是非启动程序

假设我有一个较大的Java应用程序的jar文件,但无法从源代码重新生成。我们还可以规定,我希望通过消除导致该行为的枚举值来修改应用程序不良行为的一个方面。我是否可以从相应的.class文件中删除枚举的一个值,重新创建它所属的jar,并实现一个功能仍然正常的应用程序的目标?实现这一目标的方法是什么?可能的缺点是什么

只需要使用JDK中可用的工具的答案比需要额外的工具(如中列出的工具)更好。如果它有答案,这将是有用的


对应用程序进行更改以执行反射、动态字节码操作或对枚举值进行运行时修改都是非启动程序

最有可能:不可能

但我无法从源代码重新生成

换句话说:您不能将其编译为“项目”。因此,您缺少这样一个项目定义所附带的基本工具(例如:易于访问“用法”和易于重构)

让我们假设您以某种方式将一个Enum java文件编译成一个类文件。当然,当这起作用时,您可以进入,删除相应的常量,构建一个新的.class文件,并操作现有的JAR文件来利用它

但最大的缺点是:你不知道还有多少其他类在使用这个特定常数。也许,使用javap、grep和诸如此类的东西,您可以识别该常量的用法。但是,唉,这没有帮助。因为知道某个类使用enum E.y并不能告诉您必须如何操作该类才能安全地删除E.y

另一方面,您假设此更改将导致大型应用程序以某种方式避免不必要的行为。结论:该常数似乎有许多用法。你认为这些代码将来应该做什么?当然,切换案例不再执行了。但是,将常量作为参数传递的方法调用呢?!更糟糕的是:那些使用
ordinal()
方法处理特定枚举或反射(从上帝知道的原始字符串创建枚举常量)的“聪明”人呢

长话短说:当然,理论上,您可以轻松地删除枚举常量。但这样做的结果很可能不会可靠地起作用


相反,退后一步。不要从类和检查枚举常量的角度来看待应用程序。考虑一下它的功能和模块,确定哪些“整体组件”可以从该系统中安全地切割/更换

此外,如果枚举的某些值(甚至没有在开关中使用)被删除,是否可以保证“switch(myEnumValue)”的编译代码仍然正常工作?据我们所知,编译后的代码基于序数值进行分派-这似乎纯粹是一种内部语言问题。@另一个dave未指定,但所有常见编译器都为使用序数的
switch
语句生成代码,但如果自编译后已修改
枚举
,则将重新映射数字。所以这是可行的。但是,有一个逻辑问题:如果枚举常量导致问题,某些代码会主动使用它,因此如果该常量不再存在,它将中断。但是如果您可以将代码更改为不再使用常量,则无需将其从声明中删除。