Comment obtenir le nom d'une méthode en cours d'exécution?

1. Vue d'ensemble

Parfois, nous avons besoin de connaître le nom de la méthode Java en cours d'exécution.

Cet article rapide présente quelques méthodes simples pour obtenir le nom de la méthode dans la pile d'exécution actuelle.

2. Java 9: ​​API Stack-Walking

Java 9 a introduit l'API Stack-Walking pour parcourir les cadres de la pile JVM de manière paresseuse et efficace. Afin de trouver la méthode en cours d'exécution avec cette API, nous pouvons écrire un test simple:

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

Tout d'abord, nous obtenons une instance de StackWalker à l'aide de la méthode d'usine getInstance () . Ensuite, nous utilisons la méthode walk () pour parcourir les cadres de la pile de haut en bas:

  • La méthode walk () peut convertir un flux de cadres de pile - Stream - à quoi que ce soit
  • Le premier élément du flux donné est le cadre supérieur de la pile
  • Le cadre supérieur de la pile représente toujours la méthode en cours d'exécution

Par conséquent, si nous obtenons le premier élément du flux, nous connaîtrons les détails de la méthode en cours d'exécution. Plus spécifiquement, nous pouvons utiliser StackFrame.getMethodName () pour trouver le nom de la méthode.

2.1. Avantages

Par rapport à d'autres approches (plus d'informations plus tard), l'API Stack-Walking présente quelques avantages:

  • Pas besoin de créer une instance de classe interne anonyme factice - new Object (). GetClass () {}
  • Pas besoin de créer une exception factice - nouveau Throwable ()
  • Pas besoin de capturer avec empressement l'ensemble du stacktrace, ce qui peut être coûteux

Au contraire, le StackWalker ne parcourt la pile qu'un par un de manière paresseuse. Dans ce cas, il ne récupère que la trame supérieure, contrairement à l'approche stacktrace qui capture toutes les trames avec empressement.

En fin de compte, utilisez l'API Stack-Walking si vous utilisez Java 9+.

3. Utilisation de getEnclosingMethod

Nous pouvons trouver le nom de la méthode en cours d'exécution en utilisant l' API getEnclosingMethod () :

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

4. Utilisation de la fonction Throwable Stack Trace

L'utilisation d'une trace de pile Throwable nous donne une trace de pile avec la méthode en cours d'exécution:

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

5. Utilisation de Thread Stack Trace

De plus, la trace de pile d'un thread courant (depuis JDK 1.5) inclut généralement le nom de la méthode en cours d'exécution:

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

Cependant, nous devons nous rappeler que cette solution présente un inconvénient majeur. Certaines machines virtuelles peuvent ignorer un ou plusieurs cadres de pile. Bien que ce ne soit pas courant, nous devons être conscients que cela peut arriver.

6. Conclusion

Dans ce tutoriel, nous avons présenté quelques exemples sur la manière d'obtenir le nom de la méthode actuellement exécutée. Les exemples sont basés sur des traces de pile et sur getEnclosingMethod () .

Comme toujours, vous pouvez consulter les exemples fournis dans cet article sur GitHub. De plus, des exemples Java 9 sont disponibles dans notre module Java 9 GitHub.