Java:如何获取传递给调用此方法的方法的参数?

问题描述 投票:19回答:6

在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的源,这将成为我的调试类的功能,该类事先不知道源)

谢谢。

java debugging arguments stack-trace inflection
6个回答
4
投票

我认为使用标准Java API不可能做到这一点。

[您可以做的是使用AspectJ,在调用方法上放置一个切入点,保存参数,在被调用方法上放置一个切入点,然后传递参数。

另一个选项(稍微高级一些)是使用自定义的字节码重写类加载器,该加载器保存原始参数,并将其作为额外参数传递给下一个方法。实施可能需要一两天。合适的框架是BCELASM


2
投票

我认为这是可能的,因为input超出范围,但尚无法进行垃圾回收,因此该值仍然存在,但不幸的是,我不相信有默认的API方式可以访问它。对于日志记录方法,可以使用自定义实现的NDC(嵌套的诊断上下文)来实现。


0
投票

我不确定您为什么要用Java做到这一点?

我能想到的唯一方法是为传递的字符串创建一个自定义包装对象,从而每次将引用发送到包装而不是新字符串。不过,我建议不要这样做,因为它会使您的原始代码混乱,并使它更容易出错。

可能无法使用调试器(如eclipse内置的调试器)来检查您的状态来解决此问题吗?


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()

但是要确保执行流程设置了值然后再检索它

希望我的回答为这个问题添加一些有价值的内容


-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”,方法名称按被调用的顺序(反向)。


-4
投票

这可以通过使用反射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());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.