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

时间:2019-04-28 16:56:50

标签: java enums bytecode bytecode-manipulation

可以说我有一个比较大的Java应用程序的jar文件,但是我无法从源代码重新生成。让我们还规定,我想通过消除引起该错误的枚举值来修改应用程序不良行为的一个方面。我可以从其对应的.class文件中删除枚举的值之一,重新创建它所属的jar,并实现仍可运行的应用程序的目标吗?有什么方法可以做到这一点,还有哪些弊端?

仅需要使用JDK中可用工具的答案比要求额外工具(例如this question中列出的工具)更可取。如果有答案,此similar question会很有用。

对应用程序进行更改以执行反射,动态字节码操作或对枚举值ala this question进行运行时修改是非入门的。

1 个答案:

答案 0 :(得分:2)

最有可能:不可能。

  

但是我无法从源中重新生成

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

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

但是最大的缺点是:您不知道还有多少其他类正在使用该特定常量。也许,使用javap和grep等工具,您可能能够识别该常量的用法。但是a,这无济于事。因为知道某个类使用枚举E.y根本无法告诉您如何,所以您必须操纵该类,以便可以安全地删除E.y!

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

长话短说:当然,从理论上讲,您可以轻松删除枚举常量。但是最有可能的是,这样做的结果将不能可靠地工作。

相反:退后一步。不要以类和枚举常量来查看您的应用程序。考虑其功能和模块,而是确定可以从该系统中/内部安全地剪切/替换哪些“整个组件”。