Hoe krijg ik een naam van een methode die wordt uitgevoerd?

1. Overzicht

Soms moeten we de naam weten van de huidige Java-methode die wordt uitgevoerd.

Dit korte artikel presenteert een aantal eenvoudige manieren om de naam van de methode in de huidige uitvoeringsstapel te achterhalen.

2. Java 9: ​​API voor stapelen

Java 9 introduceerde de Stack-Walking API om de JVM-stackframes op een luie en efficiënte manier te doorlopen. Om de momenteel uitgevoerde methode met deze API te vinden, kunnen we een eenvoudige test schrijven:

openbare leegte gegevenJava9_whenWalkingTheStack_thenFindMethod () {StackWalker walker = StackWalker.getInstance (); Optioneel methodName = walker.walk (frames -> frames .findFirst () .map (StackWalker.StackFrame :: getMethodName)); assertTrue (methodName.isPresent ()); assertEquals ("givenJava9_whenWalkingTheStack_thenFindMethod", methodName.get ()); }

Ten eerste krijgen we een StackWalker instantie met behulp van de getInstance () fabrieks methode. Dan gebruiken we de wandelen() methode om de stapelframes van boven naar beneden te doorlopen:

  • De wandelen() methode kan een stroom stackframes converteren - Stroomvoor alles
  • Het eerste element in de gegeven stream is het bovenste frame op de stapel
  • Het bovenste frame op de stapel vertegenwoordigt altijd de methode die momenteel wordt uitgevoerd

Daarom, als we het eerste element uit de stream halen, kennen we de details van de momenteel uitgevoerde methode. Specifieker, we kunnen gebruiken StackFrame.getMethodName () om de naam van de methode te vinden.

2.1. Voordelen

Vergeleken met andere benaderingen (daarover later meer), heeft de Stack-Walking API een paar voordelen:

  • Het is niet nodig om een ​​dummy anonieme instantie van de binnenklasse te maken - nieuw object (). getClass () {}
  • Het is niet nodig om een ​​dummy-uitzondering te maken - nieuwe Throwable ()
  • Het is niet nodig om gretig de hele stacktrace vast te leggen, wat kostbaar kan zijn

Integendeel, de StackWalker loopt alleen de stapel een voor een op een luie manier. In dit geval haalt het alleen het bovenste frame op, in tegenstelling tot de stacktrace-benadering die alle frames gretig vangt.

Het komt erop neer dat u de Stack-Walking API gebruikt als u Java 9+ gebruikt.

3. Met behulp van getEnclosingMethod

We kunnen de naam van de methode die wordt uitgevoerd vinden door de getEnclosingMethod () API:

openbare ongeldige gegevenObject_whenGetEnclosingMethod_thenFindMethod () {String methodName = new Object () {} .getClass () .getEnclosingMethod () .getName (); assertEquals ("givenObject_whenGetEnclosingMethod_thenFindMethod", methodName); }

4. Met behulp van Gooibaar Stapeltracering

Gebruik maken van een Gooibaar stacktrace geeft ons stacktracering met de methode die momenteel wordt uitgevoerd:

openbare leegte gegevenThrowable_whenGetStacktrace_thenFindMethod () {StackTraceElement [] stackTrace = nieuwe Throwable (). getStackTrace (); assertEquals ("givenThrowable_whenGetStacktrace_thenFindMethod", stackTrace [0] .getMethodName ()); }

5. Draadstapel traceren gebruiken

Ook bevat de stacktracering van een huidige thread (sinds JDK 1.5) meestal de naam van de methode die wordt uitgevoerd:

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

We moeten echter niet vergeten dat deze oplossing één belangrijk nadeel heeft. Sommige virtuele machines kunnen een of meer stapelframes overslaan. Hoewel dit niet gebruikelijk is, moeten we ons ervan bewust zijn dat dit kan gebeuren.

6. Conclusie

In deze zelfstudie hebben we enkele voorbeelden gegeven van hoe u de naam van de momenteel uitgevoerde methode kunt krijgen. Voorbeelden zijn gebaseerd op stacktraces en de getEnclosingMethod ().

Zoals altijd kun je de voorbeelden in dit artikel bekijken op GitHub. Er zijn ook Java 9-voorbeelden beschikbaar in onze Java 9 GitHub-module.


$config[zx-auto] not found$config[zx-overlay] not found