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

时间:2011-02-09 10:31:28

标签: java debugging arguments stack-trace inflection

在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的源代码,这将是我的调试类的一个功能,它不会事先知道源代码)

感谢。

6 个答案:

答案 0 :(得分:4)

我不相信使用标准Java API是可行的。

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

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

答案 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());
    }
}