在java中,可以获取调用当前方法的类和方法(获取StackTrace的方法)。
我的问题是,我可以获取传递给调用此方法的方法的参数吗?
我需要这个用于调试目的。
例如:
baseClass {
initialFunc(input) {
var modifiedInput = input + " I modified you";
otherClass.doSomething(modifiedInput);
}
}
otherClass {
doSomething(input) {
//GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
}
}
可以从堆栈跟踪中获取此信息,还是有其他方法?
(请注意,我需要能够在运行时执行此操作,并且实际上无法更改baseClass的源代码,这将是我的调试类的一个功能,它不会事先知道源代码)
感谢。
答案 0 :(得分:4)
我不相信使用标准Java API是可行的。
你可以做的是使用AspectJ,在调用方法上放置一个切入点,保存参数,在被调用的方法上放置一个切点并传递参数。
另一个选项(略高级)是使用自定义的字节码重写类加载器来保存原始参数,并将它们作为额外参数传递给下一个方法。这可能需要一两天才能实现。合适的框架是BCEL或ASM。
答案 1 :(得分:2)
我认为这可能是可能的,因为input
超出范围但尚无法进行垃圾回收,因此值仍然存在,但不幸的是我不相信有一种默认的API方式访问它。对于日志记录方法,可以使用自定义实现的NDC(嵌套诊断上下文)来实现这一点。
答案 2 :(得分:0)
我不确定你为什么要用Java做这个?
我能想到的唯一方法是为传递的字符串创建一个自定义包装器对象,从而每次都将引用发送给包装器而不是新的字符串。
不过,我建议不要这样做,因为它会使你的原始代码变得混乱,并使它更容易出错。
使用调试器(例如内置于eclipse中的调试器)来检查你的状态可能无法解决这个问题吗?
答案 3 :(得分:0)
对于我来说,我需要获取已传递到某个堆栈帧中方法的参数值,以便稍后在执行流程中使用
我使用ThreadLocal
进行存储,并且在需要时可以在代码中的任何时候检索它,就像我声明为public static
这是一个骨架的例子
public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);
methodWithImportantParam(SomeType importantValue){
// save it in the static threadLocal Field
this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
// continue method logic
}
以及在代码中您需要该值的某个地方
YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()
但是请确保您先设置了值然后再检索它
希望我的回答为该问题添加一些有价值的内容
答案 4 :(得分:-2)
您可以获取调用方法及其类的名称,但必须在当前方法中添加一些代码:
public static void main(String[] args) throws Exception {
call();
}
private static void call() {
Exception exception = new Exception();
for(StackTraceElement trace : exception.getStackTrace()){
System.out.println(trace.getMethodName());
}
}
这将打印“call”和“main”,方法名称按被叫顺序(反向)。
答案 5 :(得分:-4)
这可以使用Reflection API!
public class StackTrace {
public static void main(String args[]) {
StackTrace st = new StackTrace();
st.func();
}
public void func() {
OtherClass os =new OtherClass();
os.getStackTrace(this);
}
}
class OtherClass {
void getStackTrace(Object obj) {
System.out.println(obj.getClass());
}
}