Java: как получить аргументы, переданные методу, вызвавшему этот метод?

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

Можно ли получить эту информацию из stacktrace или есть другие средства?

(Обратите внимание, что мне нужно иметь возможность сделать это во время выполнения и не может фактически изменить источник baseClass, это будет особенностью моего класса отладки, который заранее не знает источник)

Спасибо.

Ответы

Ответ 1

Я не считаю, что это возможно с использованием стандартного Java API.

Что вы можете сделать, так это использовать AspectJ, поместить точечный снимок в вызывающий метод, сохранить аргументы, поместить вырезанную точку в вызываемом методе и передать аргументы.

Другой вариант (немного более продвинутый) заключается в использовании пользовательского, байтово-переписывающего, загрузчика классов, который сохраняет исходные аргументы и передает их в качестве дополнительных аргументов для следующего метода. Для реализации этого, вероятно, потребуется день или два. Подходящие рамки BCEL или ASM.

Ответ 2

Я думаю, что это возможно, потому что input выходит за пределы области видимости, но пока недоступен для сбора мусора, поэтому значение все еще существует, но, к сожалению, я не верю, что есть способ API по умолчанию для доступа к нему, Возможно, это возможно с помощью настраиваемого NDC (вложенного диагностического контекста) для подхода к регистрации.

Ответ 3

Я не уверен, почему вы хотели бы сделать это на Java?

Единственный способ, с помощью которого я могу думать, - создать пользовательский объект-оболочку для переданной строки, тем самым каждый раз отправляя ссылку на оболочку вместо новой строки.
Я бы советовал против этого, поскольку, поскольку он загромождает ваш исходный код и делает его еще более склонным к ошибкам.

Возможно, эта проблема не будет решена с помощью отладчика, например встроенного в eclipse, для проверки вашего состояния?

Ответ 4

Вы можете получить имя метода вызова и его класс, но вам нужно добавить код в текущий метод:

    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

Это возможно с помощью 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());
    }
}