开发者

How to get arguments passed to method that called this method?

开发者 https://www.devze.com 2023-02-09 17:15 出处:网络
In Java, it is possible to get the class and method that called the current method (the method in which you get the StackTrace).

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)


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.


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.


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?


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


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


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号