Получение имени текущего выполняемого метода - PullRequest
433 голосов
/ 14 января 2009

Есть ли способ получить имя выполняемого в настоящее время метода в Java?

Ответы [ 20 ]

12 голосов
/ 22 сентября 2015

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

new Exception("is not thrown").getStackTrace()[1].getMethodName()

Это работает на моем MacBook, а также на моем телефоне Android

Я тоже пробовал:

Thread.currentThread().getStackTrace()[1]

но Android вернет "getStackTrace" Я мог бы исправить это для Android с

Thread.currentThread().getStackTrace()[2]

но тогда я получаю неправильный ответ на своем MacBook

10 голосов
/ 02 ноября 2015

Util.java:

public static String getCurrentClassAndMethodNames() {
    final StackTraceElement e = Thread.currentThread().getStackTrace()[2];
    final String s = e.getClassName();
    return s.substring(s.lastIndexOf('.') + 1, s.length()) + "." + e.getMethodName();
}

SomeClass.java:

public class SomeClass {
    public static void main(String[] args) {
        System.out.println(Util.getCurrentClassAndMethodNames()); // output: SomeClass.main
    }
}
4 голосов
/ 15 декабря 2014

Альтернативным методом является создание, но не создание исключения, и использование этого объекта для получения данных трассировки стека, поскольку метод включения будет , как правило, , в индекс 0 - пока JVM хранит эту информацию, как уже упоминалось выше. Однако это не самый дешевый метод.

С Throwable.getStackTrace () (это было так же, как минимум с Java 5):

Нулевой элемент массива (при условии, что длина массива не равна нулю) представляет вершину стека, что является последним вызовом метода в последовательности. Обычно , это точка, в которой этот бросаемый объект был создан и брошен.

В приведенном ниже фрагменте предполагается, что класс не является статичным (из-за getClass ()), но это в стороне.

System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());
4 голосов
/ 03 июня 2013
String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);
4 голосов
/ 14 сентября 2018

Это можно сделать с помощью StackWalker начиная с Java 9.

public static String getCurrentMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(1).findFirst())
                      .get()
                      .getMethodName();
}

public static String getCallerMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(2).findFirst())
                      .get()
                      .getMethodName();
}

StackWalker разработан для того, чтобы быть ленивым, поэтому он, вероятно, будет более эффективным, чем, скажем, Thread.getStackTrace, который охотно создает массив для всего стека вызовов. Также см. JEP для получения дополнительной информации.

3 голосов
/ 08 ноября 2016

Я не знаю, каково намерение получить имя исполняемого в данный момент метода, но если это только для целей отладки, то здесь могут помочь такие каркасы журналирования, как "logback". Например, при входе в систему все, что вам нужно сделать, это использовать шаблон "% M" в вашей конфигурации . Тем не менее, это следует использовать с осторожностью, поскольку это может ухудшить производительность.

3 голосов
/ 03 марта 2016

У меня есть решение с помощью этого (в Android)

/**
 * @param className       fully qualified className
 *                        <br/>
 *                        <code>YourClassName.class.getName();</code>
 *                        <br/><br/>
 * @param classSimpleName simpleClassName
 *                        <br/>
 *                        <code>YourClassName.class.getSimpleName();</code>
 *                        <br/><br/>
 */
public static void getStackTrace(final String className, final String classSimpleName) {
    final StackTraceElement[] steArray = Thread.currentThread().getStackTrace();
    int index = 0;
    for (StackTraceElement ste : steArray) {
        if (ste.getClassName().equals(className)) {
            break;
        }
        index++;
    }
    if (index >= steArray.length) {
        // Little Hacky
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[3].getMethodName(), String.valueOf(steArray[3].getLineNumber())}));
    } else {
        // Legitimate
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[index].getMethodName(), String.valueOf(steArray[index].getLineNumber())}));
    }
}
2 голосов
/ 20 февраля 2018

На всякий случай, если метод, имя которого вы хотите узнать, является тестовым методом junit, тогда вы можете использовать правило TestName junit: https://stackoverflow.com/a/1426730/3076107

2 голосов
/ 27 сентября 2016
MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();
0 голосов
/ 25 августа 2014

Что не так с этим подходом:

class Example {
    FileOutputStream fileOutputStream;

    public Example() {
        //System.out.println("Example.Example()");

        debug("Example.Example()",false); // toggle

        try {
            fileOutputStream = new FileOutputStream("debug.txt");
        } catch (Exception exception) {
             debug(exception + Calendar.getInstance().getTime());
        }
    }

    private boolean was911AnInsideJob() {
        System.out.println("Example.was911AnInsideJob()");
        return true;
    }

    public boolean shouldGWBushBeImpeached(){
        System.out.println("Example.shouldGWBushBeImpeached()");
        return true;
    }

    public void setPunishment(int yearsInJail){
        debug("Server.setPunishment(int yearsInJail=" + yearsInJail + ")",true);
    }
}

И прежде чем люди сойдут с ума от использования System.out.println(...), вы всегда можете и должны создать какой-то метод, чтобы вывод мог быть перенаправлен, например:

    private void debug (Object object) {
        debug(object,true);
    }

    private void dedub(Object object, boolean debug) {
        if (debug) {
            System.out.println(object);

            // you can also write to a file but make sure the output stream
            // ISN'T opened every time debug(Object object) is called

            fileOutputStream.write(object.toString().getBytes());
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...