首页 > 解决方案 > 我可以从 Java 类文件中删除枚举值吗?

问题描述

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

仅需要使用 JDK 中可用的工具的答案比需要额外工具(例如此问题中列出的工具)更可取。如果有答案,这个类似的问题会很有用。

更改应用程序以执行反射、动态字节码操作或对枚举值的运行时修改(这个问题)不是初学者。

标签: javaenumsbytecodebytecode-manipulation

解决方案


最有可能:不可能。

但我无法从源头重新生成

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

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

但最大的缺点是:您知道有多少其他类正在使用该特定常量。也许,使用 javap 和 grep 之类的,您可能能够识别该常量的用法。但很可惜,这无济于事。因为知道某些类使用枚举 Ey 根本不会告诉您必须如何操作该类,以便您可以安全地删除 Ey!

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

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

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


推荐阅读