如何修改或替换 java class 中的私有方法

How to modify or substitute private method in a java class

我有一个 class 我想改变的行为。我需要用另一种实现替换私有方法。常见的反射技术允许修改私有变量或调用私有方法。但是我找不到关于替换整个方法的信息。

我认为有先进的技术可以做到这一点。标准 java 反射可能是不可能的,但可能还有其他工具可以在运行时重新编译字节码。

无需采用高级技术,有一个简单的技巧即可实现。

如果您 class 是开源 jar 的一部分,请从 grepcode.com 获取此 class 文件的源代码。更改要更改的方法并编译它。并使用更新后的 class 文件更新您的 jar file/classpath。

修改替换:

一个选项是用修改后的副本屏蔽class(修改代码,重新编译代码,将修改后的class添加到class路径之前 已修补 classes),类似于 used here 检查通常不可用方法如何工作的方法。

如果您没有要修改的源代码,您可以使用 decompilers "reverse" 几乎任何 .class 文件到或多或少可读的源代码。请注意,根据许可,您可能无权这样做 and/or 以重新分发您的更改。

通过代理打补丁:

您还可以使用 -javaagent:<jarpath>[=<options>] 命令行选项修补这些方法。 "agent" 是一个 jar,可以修改加载的 classes 并改变它们的行为。 More information here.

模拟:

如果您可以控制调用方法的地方,您可以用存根版本替换目标实例。 Mockito 等库使这变得非常非常简单:

LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

即使 Mockito 本身不支持模拟私有方法(主要是因为查看其他 classes 的私有方法被认为是不礼貌的),使用 PowerMock 允许您这样做(感谢, @talex).

您不能在运行时替换方法(至少不能侵入 JVM)。但是你可以替换整个 class。有几种方法可以做到这一点。例如,您可以使用名为 "aspect".

的东西

但根据我的经验,我可以说如果你需要这样做,你在开始的地方转错了方向。

或许你最好退一步,纵观全局