【问题标题】:How to change methods in .class file without recompiling如何在不重新编译的情况下更改 .class 文件中的方法
【发布时间】:2011-03-04 09:26:10
【问题描述】:

我需要更改现有的已编译 .class 文件。实际上我什至有它的来源,但我不能只是更改和重新编译它,因为我没有许多依赖项。

所以我需要更改 2 个方法。它们都有 void 返回类型。第一行仅包含 2 行,它们是对同一类的另一个方法的调用,即

public void a() {
    System.out.println("a");
}

public void b() {
    System.out.println("b");
}

public void ca() {
    a();
    b();

}

我需要更改方法 ca sp,它只调用 a() 方法。

我需要更改的第二种方法包含一些逻辑,但我想完全清除它,即拥有一个空主体的方法,它什么都不做。

我该怎么做?

【问题讨论】:

  • 但是,如果您没有该类的依赖项,您将如何运行该类呢?

标签: java class reflection decompiling


【解决方案1】:

如果您没有所需的依赖项,您希望如何使用此代码?我强烈建议您花时间能够正常编译它,而不是仅仅尝试更改二进制文件。从长远来看,这可能是一个更好的选择。

【讨论】:

  • >> 您希望如何使用此代码?此类是我们需要更改的大型应用程序的一部分。但是所有依赖都位于客户端,我们无法获取它们
  • @Mikhail:那么为什么你没有依赖项,或者你为什么不能掌握它们?试图只在工作环境的一部分上前进真的不是一个好主意。
  • 还有一个问题,在将代码提供给客户之前,您将如何测试您的更改?
【解决方案2】:

我会查看AspectJ 并为每次调用 ca 设置触发器。然后,您可以轻松阻止该调用并改为调用 a。

【讨论】:

    【解决方案3】:

    在 Java 字节码编辑器上试试这个问题。

    java bytecode editor?

    但是,我认为 Jon Skeet 的回答在这里真正适用。

    【讨论】:

      【解决方案4】:

      我不确定您是否可以首先更改它,但即使您确实成功了,我也不建议您这样做。更简洁的解决方案是扩展您的类并覆盖 ca() 方法的实现,以仅调用 a() 方法。

      【讨论】:

      • 我不能这样做,因为这个类是应用程序的一部分,我无法重写以使用我的新类。
      【解决方案5】:

      如果方法a 是公开的,那么最简单的方法是使用方面(Aspect Oriented ProgrammingAspectJ)并拦截对ca 的每个调用。而不是调用ca,只需调用a

      【讨论】:

      • 这是个好主意,但我无法向应用程序添加需要更改的方面。无论如何,谢谢!
      • 完全不要更改应用程序。用方面来操纵它。如果您不允许使用方面,那完全是另一回事。
      【解决方案6】:

      您是否尝试过观察反射?我对它的经验有限,但我不确定你想做什么。

      【讨论】:

        【解决方案7】:

        您可以使用Javaasist库来修改现有的类文件。

        【讨论】:

          【解决方案8】:

          我也遇到过类似的问题。

          我不得不修改没有源代码的类文件中的方法。 该方法严重地重新抛出异常,因此我不得不对其进行调整。 我已经用 Classfile Analyzer (http://classfileanalyzer.javaseiten.de/) 反编译了这个类 我已经编辑了结果文件并使用 Jasmine 汇编器重新编译它。

          使用 Apache BCEL,您可以完成同样的事情,但以更优雅的方式 - 在运行时 - 不像我在上面在编译时所描述的那样。

          【讨论】:

            【解决方案9】:

            您可以使用 java 反编译器打开类文件并对其进行编辑和保存。

            这是一个很好的解压缩 --> http://java.decompiler.free.fr/

            【讨论】:

              猜你喜欢
              • 2012-12-13
              • 1970-01-01
              • 2010-09-07
              • 1970-01-01
              • 1970-01-01
              • 2013-06-06
              • 2022-06-28
              • 2013-01-21
              • 2018-05-25
              相关资源
              最近更新 更多