Рубрики
Без рубрики

Как получить имя выполняемого метода?

Узнайте, как узнать имя выполняемого метода.

Автор оригинала: baeldung.

1. Обзор

Иногда нам нужно знать имя текущего выполняемого метода Java.

В этой краткой статье представлено несколько простых способов получения имени метода в текущем стеке выполнения.

2. Java 9: API для работы со стеком

Java 9 представила API для обхода стека для ленивого и эффективного обхода кадров стека JVM. Чтобы найти выполняемый в данный момент метод с помощью этого API, мы можем написать простой тест:

public void givenJava9_whenWalkingTheStack_thenFindMethod() {
    StackWalker walker = StackWalker.getInstance();
    Optional methodName = 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() {
    StackTraceElement[] stackTrace = new Throwable().getStackTrace();
 
    assertEquals(
      "givenThrowable_whenGetStacktrace_thenFindMethod",
      stackTrace[0].getMethodName());
}

5. Использование Трассировки Стека потоков

Кроме того, трассировка стека текущего потока (начиная с JDK 1.5) обычно включает имя выполняемого метода:

public void givenCurrentThread_whenGetStackTrace_thenFindMethod() {
    StackTraceElement[] stackTrace = Thread.currentThread()
      .getStackTrace();
 
    assertEquals(
      "givenCurrentThread_whenGetStackTrace_thenFindMethod",
      stackTrace[1].getMethodName()); 
}

Однако мы должны помнить, что у этого решения есть один существенный недостаток. Некоторые виртуальные машины могут пропускать один или несколько кадров стека. Хотя это не часто встречается, мы должны знать, что это может произойти.

6. Заключение

В этом уроке мы представили несколько примеров того, как получить

В этом уроке мы представили несколько примеров того, как получить