我想打印出带有参数名称和值的 Java 方法调用,并返回结果。
我不想手动添加跟踪语句,尤其是当代码位于第三方库中时。我需要了解与库的交互,尤其是使用回调时。
我尝试过使用包装器,但遇到了问题,所以子类化更好。 (即wrappedObject.methodA()或super.methodA()调用)
编写这段代码很痛苦,尤其是当有很多方法时。
我希望 Java 能够自动完成这项工作,因为它拥有一切可以轻松实现这一点的能力。
执行此操作的最佳方法是什么?用包装器或子类替换对象是一种折衷方案。
因此,下一步是将跟踪代码添加到包装器或子类中。我想到编写一个解析器来生成代码。
我以前使用过 yacc 和 lex,最近才知道 Antlr。
Antlr 是执行此操作的正确工具吗?请问我该怎么做呢?我以前没有使用过 Antlr,但见过它。
谢谢。
这就是我想做的 -
// 3rdParty library under investigation, with evolving versions
import com.3rdParty.lib.Service;
import com.3rdParty.lib.Callback;
MyExistingClass {
Service service = new Service();
// Need to understand 3rd party library service and callback interactions
// Also need to write my own callbacks using 3rd party interface
if (traceMethod1) {
service.doSomething(param1, new CallbackWrapper(), param3);
}
else if (traceMethod2) {
service.doSomething(param1, new CallbackSubclass(), param3);
}
else {
// Original code
// Service calls Callback methods
service.doSomething(param1, new Callback(), param3);
}
}
--------------------------------------------------------------------------------
// 3rd Party code - Service calls Callback methods
package com.3rdParty.lib;
public Callback extends SomeBaseClass {
public void methodA(int code, String action, SomeClass data) {
// do method A stuff
}
public String methodB(String name, boolean flag) {
// do method B stuff
return result;
}
...etc.
}
--------------------------------------------------------------------------------
// Wrapper class - traceMethod1
package com.my.package;
import com.3rdParty.lib.Callback;
public CallbackWrapper implements SomeCallbackInterface {
Callback cb = new Callback();
public void methodA(int code, String action, SomeClass data) {
logger.debug("CallbackWrapper.methodA() called");
logger.debug(" code = " + code);
logger.debug(" action = " + action);
logger.debug(" data = " + data);
cb.methodA(code, action, data);
logger.debug("CallbackWrapper.methodA() returns");
}
public String methodB(String name, boolean flag) {
logger.debug("CallbackWrapper.methodB() called");
logger.debug(" name = " + name);
logger.debug(" flag = " + flag);
String result = cb.methodB(name, flag);
logger.debug("CallbackWrapper.methodB() returns result = " + result);
return result;
}
...etc.
}
--------------------------------------------------------------------------------
// Subclass - traceMethod2
package com.my.package;
import com.3rdParty.lib.Callback;
public CallbackSubclass extends Callback {
public void methodA(int code, String action, SomeClass data) {
logger.debug("CallbackSubclass.methodA() called");
logger.debug(" code = " + code);
logger.debug(" action = " + action);
logger.debug(" data = " + data);
super.methodA(code, action, data);
logger.debug("CallbackSubclass.methodA() returns");
}
public String methodB(String name, boolean flag) {
logger.debug("CallbackSubclass.methodB() called");
logger.debug(" name = " + name);
logger.debug(" flag = " + flag);
String result = super.methodB(name, flag);
logger.debug("CallbackSubclass.methodB() returns result = " + result);
return result;
}
...etc.
}
最佳答案
在 Java 中执行此类操作的最简单方法是使用字节代码而不是源代码。使用 BCEL ( https://commons.apache.org/proper/commons-bcel/ ) 或 ASM ( http://asm.ow2.org/ ),您可以动态创建和加载现有类的修改版本,甚至从头开始生成全新的类。
这仍然不容易,但比尝试进行源代码翻译要容易得多。
对于跟踪方法调用的特定问题,您可以创建一个自定义类加载器,它会使用自定义跟踪代码自动检测它加载的每个类中的每个方法。
关于java - Antlr 是跟踪带有参数名称和值的 Java 方法调用并返回结果的正确工具吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38164283/