有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

最佳选择?编译前编辑字节码(asm)或编辑java文件

目标

  • 检测在何处对变量和变量副本进行比较
  • 在操作发生的行附近插入代码
  • 代码的目的是:每次运行该类时,使计数器增加

一般用途:使用某些参数计算执行后进行的比较和复制的数量

2个选项

注意:我总是有一个好主意。首先是java文件

1)编辑java文件


查找与正则表达式的比较,并在行附近插入代码片段 然后编译类(我的应用程序使用JavaCompiler)

2)使用ASM字节码工程


还检测我要跟踪的事件的位置,并将片段注入字节码 然后使用(已编译但已修改)类

我的问题

最好/最干净的方法是什么?有更好的方法吗


共 (3) 个答案

  1. # 1 楼答案

    如果您选择Java路线,您不想使用正则表达式,而是想要一个真正的Java解析器。所以这可能会影响你的决定。请记住,Oracle JVM包含一个,作为实现java编译器的内部私有类的一部分,因此如果您不想,实际上不必自己编写一个。但是破解Oracle AST也不是5分钟的任务。当然,如果这很重要的话,使用它是不可移植的

    如果采用ASM方法,字节码最初将更容易分析,因为语义要简单得多。就您的解决方案的净时间而言,分析的简单性是否超过了不熟悉性是未知的。最后,就生成的代码而言,两者都不是“更好”

    仅仅查看生成的java源代码并“知道”您看到的是您所得到的,而不是对类文件进行基本转储以进行调试等,这显然是一种简单的方法,但所有这些明显的简单性都存在,因为您已经具备了使用java语言的舒适性。一旦你花一些时间去挖掘字节码,它也会变得很舒服。只是一个问题,首先你是否值得花时间去那里

  2. # 2 楼答案

    一般来说,这完全取决于您对这两个选项的适应程度以及性能方面的重要性。字节码操作将更快,也更简单,但您必须了解字节码是如何工作的,以及如何使用ASM框架

    拦截变量访问可能是ASM最简单的用例之一。你可以在这篇{a1}论文中找到一些更复杂的场景

    以下是拦截变量访问的简化代码:

    ClassReader cr = ...;
    ClassWriter cw = ...;
    cr.accept(new MethodVisitor(cw) {
      public void visitVarInsn(int opcode, int var) {
        if(opcode == ALOAD) {  // loading Object var
          ... insert method call
        } 
      }
    });
    
  3. # 3 楼答案

    如果是我,我可能会使用ASM选项

    如果您需要有关ASM的教程,我偶然发现了这个用户编写的教程click here