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

Java:如何将参数传递给调用此方法的方法?,java,debugging,arguments,stack-trace,inflection,Java,Debugging,Arguments,Stack Trace,Inflection,在java中,可以获取调用当前方法的类和方法(获取StackTrace的方法) 我的问题是,我可以获取传递给调用此方法的方法的参数吗 我需要这个用于调试目的 例如: 人们可以从stacktrace中获取这些信息,还是有其他方法 (请注意,我需要能够在运行时执行此操作,并且不能实际更改基类的源代码,这将是调试类的一个功能,它事先不知道源代码) 谢谢。我认为这是可能的,因为input超出了范围,但垃圾收集还无法访问,因此该值仍然存在,但不幸的是,我不相信有默认的API方式来访问它。对于日志记录方法,

在java中,可以获取调用当前方法的类和方法(获取StackTrace的方法)

我的问题是,我可以获取传递给调用此方法的方法的参数吗

我需要这个用于调试目的

例如:

人们可以从stacktrace中获取这些信息,还是有其他方法

(请注意,我需要能够在运行时执行此操作,并且不能实际更改基类的源代码,这将是调试类的一个功能,它事先不知道源代码)


谢谢。

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

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

您可以使用AspectJ,在调用方法处放置一个切入点,保存参数,在被调用方法处放置一个切入点,然后传递参数


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

这可以使用反射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());
    }
}

我不知道你为什么要用Java做这个

我能想到的唯一方法是为传递的字符串创建一个自定义包装器对象,从而每次都将引用发送到包装器,而不是发送一个新字符串。
不过,我还是反对它,因为它会使您的原始代码变得杂乱无章,甚至更容易出错


是否可以使用eclipse内置的调试器来检查您的状态来解决此问题?

您可以获取调用方方法的名称及其类,但必须在当前方法中添加一些代码:

    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”方法名称。

在我的例子中,我需要获得一个参数值,该参数值已传递给某个堆栈帧中的方法,以便稍后在执行流中使用

我使用
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
}
但是,请确保执行流设置了值,然后检索它



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

形式参数被视为本地变量,其内容存储在堆栈上,因此从不进行垃圾收集。它根本不需要存储在堆栈上。该方法可以是内联的和/或参数可以在CPU寄存器中(这是通过“热”代码实现的)你确定没有办法访问它吗?@Tom,如果你运行调试设置,你可以使用其他代理,你可以这样做。通常你不能。@bestsss,我说的是jvm的激活记录堆栈。如果你附加一个调试器,你可以,否则-不。参数可能在CPU寄存器中(不在堆栈上)。我恐怕我不能为我的目的附加一个调试器。因此,除了类加载器和动态增强类以捕获参数之外,你会迷路。(但你不会问自己是否知道如何做)当调试器能够做到这一点时,那么它一定是可能的。另外,调试器不使用代码插装或类似的工具,因为它可以附加到任何Java进程。不知道这是怎么回事,也许是一些JMX?@bestsss,这让我想到了一个后续问题:-我接受了这个问题。AspectJ方法会迫使我在运行前更改源代码,所以这不是一个选项。关于另一个选项,我可以做一个JRE扩展来更新每个方法使用的任何类吗?如果是这样,JRE中使用的方法/函数是什么类?下面是一个类似问题的AspectJ示例:这需要我附加一个调试器吗?不需要,这是JVM内部使用的一种技术。围绕反射进行游戏真的很有趣……您可以得到调用者类-true,但不是arguments@Ujjwal,也许您可以通过复制我的代码示例来扩展您的答案,并使其输出传递给调用此方法的方法的参数。(看起来这是不可能的)单独使用反射是不可能的,因为不应该修改原始代码(=>您没有地方插入反射调用)。
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()