Java: как получить аргументы, передаваемые методу, вызвавшему этот метод? - PullRequest
17 голосов
/ 09 февраля 2011

В 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, это будет функция моего класса отладки, который не знает источникзаранее)

Спасибо.

Ответы [ 5 ]

4 голосов
/ 09 февраля 2011

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

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

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

2 голосов
/ 09 февраля 2011

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

0 голосов
/ 01 августа 2013

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

    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", имя метода в порядке вызова(обратный).

0 голосов
/ 09 февраля 2011

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

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

Может ли эта проблема не быть решена с помощью отладчика, такого как встроенный в Eclipse, для проверки вашего состояния?

0 голосов
/ 09 февраля 2011

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