Оба эти варианта работают для меня с Java:
new Object()<>.getClass().getEnclosingMethod().getName()
Thread.currentThread().getStackTrace()[1].getMethodName()
public class SomeClass < public void foo()< class Local <>; String name = Local.class.getEnclosingMethod().getName(); > >
имя будет иметь значение foo.
Это можно сделать с помощью 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 для получения дополнительной информации.
Самый быстрый способ, который я нашел, заключается в том, что:
import java.lang.reflect.Method; public class TraceHelper < // save it static to have it available on every call private static Method m; static < try < m = Throwable.class.getDeclaredMethod("getStackTraceElement", int.class); m.setAccessible(true); >catch (Exception e) < e.printStackTrace(); >> public static String getMethodName(final int depth) < try < StackTraceElement element = (StackTraceElement) m.invoke( new Throwable(), depth + 1); return element.getMethodName(); >catch (Exception e) < e.printStackTrace(); return null; >> >
Он напрямую обращается к собственному методу getStackTraceElement(int глубине). И сохраняет доступный Метод в статической переменной.
Используйте следующий код:
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace(); StackTraceElement e = stacktrace[1];//coz 0th will be getStackTrace so 1st String methodName = e.getMethodName(); System.out.println(methodName);
public static String getCurrentMethodName()
Он предоставляет несколько статических методов для получения текущих и вызывающих имен классов / методов.
/* Utility class: Getting the name of the current executing method * https://stackru.com/questions/442747/getting-the-name-of-the-current-executing-method * * Provides: * * getCurrentClassName() * getCurrentMethodName() * getCurrentFileName() * * getInvokingClassName() * getInvokingMethodName() * getInvokingFileName() * * Nb. Using StackTrace's to get this info is expensive. There are more optimised ways to obtain * method names. See other stackru posts eg. https://stackru.com/questions/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection/2924426#2924426 * * 29/09/2012 (lem) - added methods to return (1) fully qualified names and (2) invoking class/method names */ package com.stackru.util; public class StackTraceInfo < /* (Lifted from virgo47's stackru answer) */ private static final int CLIENT_CODE_STACK_INDEX; static < // Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6 int i = 0; for (StackTraceElement ste: Thread.currentThread().getStackTrace()) < i++; if (ste.getClassName().equals(StackTraceInfo.class.getName())) < break; >> CLIENT_CODE_STACK_INDEX = i; > public static String getCurrentMethodName() < return getCurrentMethodName(1); // making additional overloaded method call requires +1 offset >private static String getCurrentMethodName(int offset) < return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getMethodName(); >public static String getCurrentClassName() < return getCurrentClassName(1); // making additional overloaded method call requires +1 offset >private static String getCurrentClassName(int offset) < return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getClassName(); >public static String getCurrentFileName() < return getCurrentFileName(1); // making additional overloaded method call requires +1 offset >private static String getCurrentFileName(int offset) < String filename = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getFileName(); int lineNumber = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getLineNumber(); return filename + ":" + lineNumber; >public static String getInvokingMethodName() < return getInvokingMethodName(2); >private static String getInvokingMethodName(int offset) < return getCurrentMethodName(offset + 1); // re-uses getCurrentMethodName() with desired index >public static String getInvokingClassName() < return getInvokingClassName(2); >private static String getInvokingClassName(int offset) < return getCurrentClassName(offset + 1); // re-uses getCurrentClassName() with desired index >public static String getInvokingFileName() < return getInvokingFileName(2); >private static String getInvokingFileName(int offset) < return getCurrentFileName(offset + 1); // re-uses getCurrentFileName() with desired index >public static String getCurrentMethodNameFqn() < return getCurrentMethodNameFqn(1); >private static String getCurrentMethodNameFqn(int offset) < String currentClassName = getCurrentClassName(offset + 1); String currentMethodName = getCurrentMethodName(offset + 1); return currentClassName + "." + currentMethodName ; >public static String getCurrentFileNameFqn() < String CurrentMethodNameFqn = getCurrentMethodNameFqn(1); String currentFileName = getCurrentFileName(1); return CurrentMethodNameFqn + "(" + currentFileName + ")"; >public static String getInvokingMethodNameFqn() < return getInvokingMethodNameFqn(2); >private static String getInvokingMethodNameFqn(int offset) < String invokingClassName = getInvokingClassName(offset + 1); String invokingMethodName = getInvokingMethodName(offset + 1); return invokingClassName + "." + invokingMethodName; >public static String getInvokingFileNameFqn() < String invokingMethodNameFqn = getInvokingMethodNameFqn(2); String invokingFileName = getInvokingFileName(2); return invokingMethodNameFqn + "(" + invokingFileName + ")"; >>
Чтобы получить имя метода, вызвавшего текущий метод, вы можете использовать:
new Exception("is not thrown").getStackTrace()[1].getMethodName()
Это работает на моем MacBook, а также на моем телефоне Android
Thread.currentThread().getStackTrace()[1]
но Android вернет "getStackTrace", я мог бы исправить это для Android с
Thread.currentThread().getStackTrace()[2]
но тогда я получаю неправильный ответ на моем MacBook
Источник
Получение имени текущего выполняемого метода в Java
Ситуации, когда необходимо получить имя текущего выполняемого метода, могут встретиться довольно часто. Например, при отладке программы или при логировании.
Ситуации, когда необходимо получить имя текущего выполняемого метода, могут встретиться довольно часто. Например, при отладке программы или при логировании. Приведем пример: есть метод, в котором происходит некоторое действие, и результат этого действия записывается в лог. В логе необходимо указать, в каком именно методе было выполнено это действие.
В таком случае возникает вопрос: как получить имя текущего метода в Java? Для этого существует несколько способов.
Способ 1. Использование StackTrace
Java предоставляет возможность получить стек вызовов для текущего потока с помощью метода Thread.currentThread().getStackTrace() . Этот метод возвращает массив StackTraceElement , каждый из которых представляет собой элемент стека вызовов. Нулевой элемент массива ( [0] ) — это сам метод getStackTrace , первый элемент ( [1] ) — это метод, который вызвал getStackTrace , и так далее. Таким образом, чтобы получить имя текущего метода, нужно обратиться к второму элементу этого массива.
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
Способ 2. Использование исключений
Другой способ получить стек вызовов — использовать исключения. Метод Throwable.getStackTrace() также возвращает массив StackTraceElement , аналогичный тому, который возвращает Thread.currentThread().getStackTrace() . Однако в этом случае нулевой элемент массива ( [0] ) — это метод, где было создано исключение.
String methodName = new Exception().getStackTrace()[0].getMethodName();
Оба этих способа позволяют получить имя текущего выполняемого метода. Однако стоит помнить, что оба способа имеют относительно высокую стоимость в плане производительности, поэтому их стоит использовать с умом и не злоупотреблять.
Источник
Как получить имя выполняемого метода?
Иногда нам нужно знать имя текущего выполняемого метода Java.
В этой краткой статье представлено несколько простых способов получения имени метода в текущем стеке выполнения.
2. Java 9: API для работы со стеком
Java 9 представила API для обхода стека для ленивого и эффективного обхода кадров стека JVM. Чтобы найти выполняемый в данный момент метод с помощью этого API, мы можем написать простой тест:
public void givenJava9_whenWalkingTheStack_thenFindMethod() < StackWalker walker = StackWalker.getInstance(); OptionalmethodName = walker.walk(frames -> frames .findFirst() .map(StackWalker.StackFrame::getMethodName)); assertTrue(methodName.isPresent()); assertEquals("givenJava9_whenWalkingTheStack_thenFindMethod", methodName.get()); >
Во-первых, мы получаем экземпляр StackWalker |, используя getInstance () |/заводской метод. Затем мы используем метод walk() для перемещения кадров стека сверху вниз:
- Метод walk() может преобразовать поток стековых кадров — Поток Стековый кадр> — во что угодно
- Первым элементом в данном потоке является верхний кадр в стеке
- Верхний кадр в стеке всегда представляет текущий выполняемый метод
Поэтому, если мы получим первый элемент из потока, мы будем знать детали текущего метода выполнения. Более конкретно, мы можем использовать Stack Frame.GetMethod() для поиска имени метода.
2.1. Преимущества
По сравнению с другими подходами (подробнее о них позже) API для обхода стека имеет несколько преимуществ:
- Нет необходимости создавать фиктивный анонимный экземпляр внутреннего класса — новый объект().getClass() <>
- Нет необходимости создавать фиктивное исключение — new Throwable()
- Нет необходимости охотно захватывать весь маршрут стека, что может быть дорогостоящим
Напротив, StackWalker только лениво ходит по стеку один за другим. В этом случае он извлекает только верхний кадр, в отличие от подхода трассировки стека, который охотно захватывает все кадры.
Суть в том, что используйте API для обхода стека, если вы используете Java 9+.
3. Использование метода Getenclosing
Мы можем найти имя выполняемого метода с помощью getEnclosingMethod() API:
public void givenObject_whenGetEnclosingMethod_thenFindMethod() < String methodName = new Object() <>.getClass() .getEnclosingMethod() .getName(); assertEquals("givenObject_whenGetEnclosingMethod_thenFindMethod", methodName); >
4. Использование Трассировки сбрасываемого Стека
Использование Выбрасываемая трассировка стека дает нам трассировку стека с выполняемым в данный момент методом:
public void givenThrowable_whenGetStacktrace_thenFindMethod()
5. Использование Трассировки Стека потоков
Кроме того, трассировка стека текущего потока (начиная с JDK 1.5) обычно включает имя выполняемого метода:
public void givenCurrentThread_whenGetStackTrace_thenFindMethod()
Однако мы должны помнить, что у этого решения есть один существенный недостаток. Некоторые виртуальные машины могут пропускать один или несколько кадров стека. Хотя это не часто встречается, мы должны знать, что это может произойти.
6. Заключение
В этом уроке мы представили несколько примеров того, как получить
В этом уроке мы представили несколько примеров того, как получить
Источник
Как получить имя исполняемого метода?
Иногда нам нужно знать имя текущего выполняемого метода Java.
В этой быстрой статье представлены несколько простых способов получить имя метода в текущем стеке выполнения.
2. ИспользуяgetEnclosingMethod
Мы можем найти имя выполняемого метода с помощью APIgetEnclosingMethod():
public void givenObject_whenGetEnclosingMethod_thenFindMethod() < String methodName = new Object() <>.getClass() .getEnclosingMethod() .getName(); assertEquals("givenObject_whenGetEnclosingMethod_thenFindMethod", methodName); >
3. Использование трассировки стекаThrowable
Использование трассировки стекаThrowable дает нам трассировку стека с методом, который выполняется в данный момент:
public void givenThrowable_whenGetStacktrace_thenFindMethod()
4. Использование трассировки стека потоков
Кроме того, трассировка стека текущего потока (начиная с JDK 1.5) обычно включает имя выполняемого метода:
public void givenCurrentThread_whenGetStackTrace_thenFindMethod()
Однако нужно помнить, что у этого решения есть один существенный недостаток. Некоторые виртуальные машины могут пропускать один или несколько кадров стека. Хотя это не часто, мы должны знать, что это может случиться.
5. Заключение
В этом уроке мы представили несколько примеров того, как получить имя выполняемого в данный момент метода. Примеры основаны на трассировках стека иgetEnclosingMethod().
Как всегда, вы можете ознакомиться с примерами из этой статьиover on GitHub.
Источник