Come ottenere un nome per un metodo in esecuzione?

1. Panoramica

A volte è necessario conoscere il nome del metodo Java corrente in esecuzione.

Questo rapido articolo presenta un paio di semplici modi per ottenere il nome del metodo nello stack di esecuzione corrente.

2. Java 9: ​​API Stack-Walking

Java 9 ha introdotto l'API Stack-Walking per attraversare gli stack frame JVM in modo pigro ed efficiente. Per trovare il metodo attualmente in esecuzione con questa API, possiamo scrivere un semplice test:

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()); }

Innanzitutto, otteniamo un'istanza StackWalker utilizzando il metodo factory getInstance () . Quindi usiamo il metodo walk () per attraversare gli stack frame dall'alto verso il basso:

  • Il metodo walk () può convertire un flusso di stack frame - Stream - a qualsiasi cosa
  • Il primo elemento nello stream specificato è il frame superiore dello stack
  • Il frame superiore dello stack rappresenta sempre il metodo attualmente in esecuzione

Pertanto, se otteniamo il primo elemento dal flusso, conosceremo i dettagli del metodo attualmente in esecuzione. Più specificamente, possiamo usare StackFrame.getMethodName () per trovare il nome del metodo.

2.1. Vantaggi

Rispetto ad altri approcci (ne parleremo più avanti), l'API Stack-Walking presenta alcuni vantaggi:

  • Non è necessario creare un'istanza di classe interna anonima fittizia: new Object (). GetClass () {}
  • Non è necessario creare un'eccezione fittizia: nuovo Throwable ()
  • Non c'è bisogno di acquisire con entusiasmo l'intero stacktrace, che può essere costoso

Al contrario, StackWalker percorre lo stack solo uno per uno in modo pigro. In questo caso, recupera solo il frame superiore, al contrario dell'approccio stacktrace che cattura tutti i frame con entusiasmo.

La conclusione è che utilizza l'API Stack-Walking se utilizzi Java 9+.

3. Utilizzo di getEnclosingMethod

Possiamo trovare il nome del metodo in esecuzione utilizzando l' API getEnclosingMethod () :

public void givenObject_whenGetEnclosingMethod_thenFindMethod() { String methodName = new Object() {} .getClass() .getEnclosingMethod() .getName(); assertEquals("givenObject_whenGetEnclosingMethod_thenFindMethod", methodName); }

4. Utilizzo di Throwable Stack Trace

L'utilizzo di una traccia dello stack Throwable ci dà la traccia dello stack con il metodo attualmente in esecuzione:

public void givenThrowable_whenGetStacktrace_thenFindMethod() { StackTraceElement[] stackTrace = new Throwable().getStackTrace(); assertEquals( "givenThrowable_whenGetStacktrace_thenFindMethod", stackTrace[0].getMethodName()); }

5. Utilizzando Thread Stack Trace

Inoltre, la traccia dello stack di un thread corrente (a partire da JDK 1.5) di solito include il nome del metodo che viene eseguito:

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

Tuttavia, dobbiamo ricordare che questa soluzione presenta uno svantaggio significativo. Alcune macchine virtuali possono saltare uno o più stack frame. Sebbene ciò non sia comune, dobbiamo essere consapevoli che ciò può accadere.

6. Conclusione

In questo tutorial, abbiamo presentato alcuni esempi di come ottenere il nome del metodo attualmente eseguito. Gli esempi sono basati sulle tracce dello stack e getEnclosingMethod () .

Come sempre, puoi controllare gli esempi forniti in questo articolo su GitHub. Inoltre, gli esempi Java 9 sono disponibili nel nostro modulo Java 9 GitHub.