544 Stimmen

Abfrage des Namens der aktuell ausgeführten Methode

Gibt es eine Möglichkeit, den Namen der gerade ausgeführten Methode in Java zu erfahren?

363voto

Devin Punkte 3441

Technisch wird das funktionieren...

String name = new Object(){}.getClass().getEnclosingMethod().getName();

Allerdings wird während der Kompilierung eine neue anonyme innere Klasse erstellt (z. B. YourClass$1.class ). Dies wird also eine .class Datei für jede Methode, die diesen Trick anwendet. Außerdem wird bei jedem Aufruf zur Laufzeit eine ansonsten ungenutzte Objektinstanz erzeugt. Dies mag also ein akzeptabler Debug-Trick sein, ist aber mit erheblichem Overhead verbunden.

Ein Vorteil dieses Tricks ist, dass getEnclosingMethod() gibt zurück. java.lang.reflect.Method die zum Abrufen aller anderen Informationen über die Methode, einschließlich Anmerkungen und Parameternamen, verwendet werden kann. Dadurch ist es möglich, zwischen bestimmten Methoden mit demselben Namen zu unterscheiden (Methodenüberladung).

Beachten Sie, dass laut der JavaDoc von getEnclosingMethod() sollte dieser Trick nicht zu einem SecurityException da die inneren Klassen mit demselben Klassenlader geladen werden sollten. Es besteht also keine Notwendigkeit, die Zugriffsbedingungen zu überprüfen, selbst wenn ein Sicherheitsmanager vorhanden ist.

Bitte beachten Sie : Es ist erforderlich, Folgendes zu verwenden getEnclosingConstructor() für Konstrukteure. Während Blöcken außerhalb von (benannten) Methoden, getEnclosingMethod() gibt zurück. null .

205voto

Bombe Punkte 77831

[Thread](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html).[currentThread()](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#currentThread()).[getStackTrace()](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#getStackTrace()) enthält normalerweise die Methode, von der aus Sie sie aufrufen, aber es gibt Fallstricke (siehe [Javadoc](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#getStackTrace()) ):

Einige virtuelle Maschinen können unter Umständen einen oder mehrere Stack-Frames aus der Stack-Trace auslassen. Im Extremfall kann eine virtuelle Maschine, die keine Stack-Trace-Informationen zu diesem Thread hat, ein Array mit der Länge Null von dieser Methode zurückgeben.

143voto

VonC Punkte 1117238

Januar 2009:
Ein vollständiger Code wäre (zur Verwendung mit @Bombe's Vorbehalt im Kopf):

/**
 * Get the method name for a depth in call stack. <br />
 * Utility function
 * @param depth depth in the call stack (0 means current method, 1 means call method, ...)
 * @return method name
 */
public static String getMethodName(final int depth)
{
  final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
  // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
  return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
}

Mehr in diese Frage .

Update Dezember 2011:

bläulich Kommentare:

Ich verwende JRE 6 und erhalte einen falschen Methodennamen.
Es funktioniert, wenn ich schreibe ste[2 + depth].getMethodName().

  • 0 es getStackTrace() ,
  • 1 es getMethodName(int depth) y
  • 2 ist eine aufrufende Methode.

virgo47 's 回答 (hochgestuft) berechnet tatsächlich den richtigen Index, der anzuwenden ist, um den Methodennamen zurückzubekommen.

93voto

virgo47 Punkte 2173

Wir haben diesen Code verwendet, um potenzielle Schwankungen im Stack-Trace-Index zu mildern - jetzt rufen Sie einfach methodName util:

public class MethodNameTest {
    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(MethodNameTest.class.getName())) {
                break;
            }
        }
        CLIENT_CODE_STACK_INDEX = i;
    }

    public static void main(String[] args) {
        System.out.println("methodName() = " + methodName());
        System.out.println("CLIENT_CODE_STACK_INDEX = " + CLIENT_CODE_STACK_INDEX);
    }

    public static String methodName() {
        return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX].getMethodName();
    }
}

Es scheint übertrieben, aber wir hatten eine feste Zahl für JDK 1.5 und waren ein wenig überrascht, dass sie sich beim Wechsel zu JDK 1.6 geändert hat. Jetzt ist sie in Java 6/7 die gleiche, aber man weiß ja nie. Es ist nicht sicher, ob sich der Index während der Laufzeit ändert - aber hoffentlich macht HotSpot das nicht so schlimm :-)

48voto

Charlie Seligman Punkte 3877

Beide Optionen funktionieren bei mir mit Java:

new Object(){}.getClass().getEnclosingMethod().getName()

Oder:

Thread.currentThread().getStackTrace()[1].getMethodName()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X