目标
- 检测变量之间的比较和副本在哪里进行
- 在操作发生的行附近注入代码
- 代码的目的:每次运行类时都会增加一个计数器
通用:计算使用某些参数执行后进行的比较和复制的数量
2 个选项
注意:我总是有一个 .java 文件开头
1)编辑java文件
查找与正则表达式的比较并在行附近注入代码片段然后编译类(我的应用程序使用JavaCompiler)
2)使用ASM字节码工程
还检测我想要跟踪的事件并将片段注入字节码然后使用(已经编译但修改)类
我的问题
最好/最干净的方法是什么?有一个更好的方法吗?
通用:计算使用某些参数执行后进行的比较和复制的数量
注意:我总是有一个 .java 文件开头
1)编辑java文件
查找与正则表达式的比较并在行附近注入代码片段然后编译类(我的应用程序使用JavaCompiler)
2)使用ASM字节码工程
还检测我想要跟踪的事件并将片段注入字节码然后使用(已经编译但修改)类
最好/最干净的方法是什么?有一个更好的方法吗?
一般来说,这一切都取决于您对任一选项的舒适程度以及性能方面的重要性。字节码操作会更快且更简单,但您必须了解字节码的工作原理以及如何使用 ASM 框架。
拦截变量访问可能是 ASM 最简单的用例之一。您可以在这篇AOSD'07论文中找到一些更复杂的场景。
下面是拦截变量访问的简化代码:
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
}
}
});
如果你选择 Java 路线,你不想使用正则表达式——你想要一个真正的 Java 解析器。所以这可能会影响你的决定。请注意,Oracle JVM 包含一个,作为实现 java 编译器的内部私有类的一部分,因此如果您不想编写,实际上不必自己编写一个。但解码 Oracle AST 也不是 5 分钟的任务。而且,当然,如果这很重要,那么使用它是不可移植的。
如果你走 ASM 路线,字节码最初会更容易分析,因为语义要简单得多。就解决方案的净时间而言,分析的简单性是否超过了不熟悉性是未知的。最后,就生成的代码而言,两者都不是“更好”的。
仅查看生成的 java 源代码并“知道”所见即所得与进行类文件的原始转储以进行调试等相比,显然很简单,但是由于您已经存在,所有这些明显的简单性都存在Java 语言的舒适度。一旦你花一些时间挖掘字节码,它也会变得舒服。只是一个问题,您是否值得花时间首先到达那里。
如果是我,我可能会使用 ASM 选项。
如果您需要有关 ASM 的教程,我偶然发现了这个用户编写的教程,请单击此处