19

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

谢谢。

4

6 回答 6

4

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

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

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

于 2011-02-09T10:36:23.317 回答
2

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

于 2011-02-09T10:35:56.287 回答
0

我不确定你为什么要在 Java 中这样做?

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

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

于 2011-02-09T10:45:39.903 回答
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()

但请确保您设置值的执行流程然后您检索它

希望我的回答能为这个问题增添一些有价值的东西

于 2020-02-26T13:09:19.107 回答
-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”,方法名称。

于 2013-08-01T11:17:20.603 回答
-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());
    }
}
于 2011-02-09T10:44:20.590 回答