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

发布于 2024-10-16 13:55:19 字数 522 浏览 2 评论 0原文

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

In Java, it is possible to get the class and method that called the current method (the method in which you get the StackTrace).

Can I get the arguments that were passed to the method that called this method?

I need this for debugging purposes.

Eg:

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
    }
}

Can one get this information from the stacktrace, or are there other means?

(Note that I need to be able to do this in runtime and cannot actually change the source of baseClass, this is going to be a feature of my debugging class that does not know the source beforehand)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

吾家有女初长成 2024-10-23 13:55:19

我不认为使用标准 Java API 可以实现这一点。

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

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

I don't believe this is possible using the standard Java API.

What you could do is to use AspectJ, place a point-cut at the calling method, save the arguments, place a point-cut at the called method and pass on the arguments.

Another option (slightly more advanced) is to use a custom, bytecode-rewriting, class loader that saves the original arguments, and passes them on as extra arguments to the next method. This would probably take a day or two to implement. Suitable frameworks are BCEL or ASM.

怼怹恏 2024-10-23 13:55:19

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

I think this could be possible, because input is out of scope but isn't yet accessible for garbage collection, so the value still exists, but unfortunately I don't believe there is an default API way to access it. This could be maybe possible with a custom implemented NDC (nested diagnostic context) for the logging approach.

总攻大人 2024-10-23 13:55:19

就我而言,我需要获取已传递给某个堆栈帧中的方法的参数值,以便稍后在执行流程中使用

,我使用 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()

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

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

In my case, I needed to get a parameter value has been passed to a method in a certain stack frame to be used later within the execution flow

I used ThreadLocal to store it and when I needed it I was able to retrieve it at any point in code as I declared it as public static

here is a skeleton example

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
}

and somewhere in code where you need that value

YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()

but make sure the execution flow that you set the value then you retrieve it

hope my answer add something valuable to this question

意犹 2024-10-23 13:55:19

我不确定你为什么想用 Java 来做这个?

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

使用调试器(例如 Eclipse 中内置的调试器)检查您的状态是否可以解决此问题?

I'm not sure why you'd ever want to do this in Java?

The only way I can think of is to create a custom wrapper object for the passed string, thus sending the reference to the wrapper instead of a new string each time.
I'd advice against it, though, since it clutters your original code, and makes it even more error prone.

Might this problem not be solved using a debugger, like the one built into eclipse, to inspect your state?

暮色兮凉城 2024-10-23 13:55:19

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

    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”,方法名称(相反)。

You can get name of caller method and its class, but you have to add some code in current method:

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

This will print "call" and "main", methods name in called order (reverse).

花开浅夏 2024-10-23 13:55:19

使用 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());
    }
}

This is possible using 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());
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文