Java или любой другой язык: Какой метод / класс вызвал мой?

Я хотел бы написать внутренний код моего метода, который выводит, какой метод / класс вызвал его.

(Я предполагаю, что я ничего не могу изменить, кроме своего метода ...)

Как насчет других языков программирования?

РЕДАКТИРОВАТЬ: Спасибо, ребята, а как насчет JavaScript? питон? C ++?

12
задан DuduAlul 12 August 2010 в 13:47
поделиться

8 ответов

Это характерно для Java.

Вы можете использовать Thread.currentThread (). getStackTrace () . Это вернет массив StackTraceElements .

Второй элемент в массиве будет вызывающим методом.

Пример:

public void methodThatPrintsCaller() {
    StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
    System.out.println(elem);

    // rest of you code
}
19
ответ дан 2 December 2019 в 04:42
поделиться

Если все, что вам нужно сделать, это распечатать трассировку стека и поискать класс, используйте

Thread.dumpStack();

См. документ API .

4
ответ дан 2 December 2019 в 04:42
поделиться

последовательность вызовов методов находится в стеке. вот как получить стек: Получить текущую трассировку стека в Java затем получить предыдущий элемент.

3
ответ дан 2 December 2019 в 04:42
поделиться

Джастин разобрал общий случай; я хотел упомянуть два особых случая, продемонстрированных этим фрагментом:

import java.util.Comparator;

public class WhoCalledMe {

    public static void main(String[] args) {
        ((Comparator)(new SomeReifiedGeneric())).compare(null, null);
        new WhoCalledMe().new SomeInnerClass().someInnerMethod();
    }

    public static StackTraceElement getCaller() {
        //since it's a library function we use 3 instead of 2 to ignore ourself
        return Thread.currentThread().getStackTrace()[3];
    }

    private void somePrivateMethod() {
        System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
    }

    private class SomeInnerClass {
        public void someInnerMethod() {
            somePrivateMethod();
        }
    }
}

class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
    public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
        System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
        return 0;
    }
}

Это печатает:

SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)

Несмотря на то, что первый вызывается "напрямую" из main(), а второй из SomeInnerClass. someInnerMethod(). Это два случая, когда между двумя методами сделан прозрачный вызов.

  • В первом случае это происходит потому, что мы вызываем bridge method к общему методу, добавленному компилятором для обеспечения возможности использования SomeReifiedGeneric в качестве необработанного типа.
  • Во втором случае это происходит потому, что мы вызываем приватный член WhoCalledMe из внутреннего класса. Для этого компилятор добавляет синтетический метод в качестве промежуточного для преодоления проблем с видимостью.
4
ответ дан 2 December 2019 в 04:42
поделиться

Поскольку вы спрашивали о других языках, Tcl дает вам команду ( информационный уровень ), которая позволяет вам исследовать стек вызовов. Например, [информационный уровень -1] возвращает вызывающего объекта текущей процедуры, а также аргументы, используемые для вызова текущей процедуры.

1
ответ дан 2 December 2019 в 04:42
поделиться

В Python вам следует использовать модули traceback или inspect. Эти модули оградят вас от деталей реализации интерпретатора, которые могут отличаться даже сегодня (например, IronPython, Jython) и могут еще больше измениться в будущем. Однако способ, которым эти модули делают это в стандартном интерпретаторе Python сегодня, - это sys._getframe(). В частности, sys._getframe(1).f_code.co_name предоставляет нужную вам информацию.

0
ответ дан 2 December 2019 в 04:42
поделиться

Да, это возможно.

Посмотрите на Thread.getStackTrace()

0
ответ дан 2 December 2019 в 04:42
поделиться

В Python вы используете осмотрите модуль . Как видно из приведенного ниже примера, получить имя функции и имя файла несложно.

Получение самой функции - это больше работы. Я думаю, вы могли бы использовать функцию __ import __ для импорта модуля вызывающего. Однако вы должны каким-то образом преобразовать имя файла в допустимое имя модуля.

import inspect

def find_caller():
    caller_frame = inspect.currentframe().f_back
    print "Called by function:", caller_frame.f_code.co_name
    print "In file           :", caller_frame.f_code.co_filename
    #Alternative, probably more portable way
    #print inspect.getframeinfo(caller_frame)

def foo():
    find_caller()

foo()
1
ответ дан 2 December 2019 в 04:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: