web-dev-qa-db-de.com

Wie bekomme ich den String-Namen einer Methode in Java?

Wie kann ich durch Nachdenken herausfinden, wie der Name der Methode lautet?

Zum Beispiel gegeben:

class Car{
   public void getFoo(){
   }
}

Ich möchte den String "getFoo" bekommen, etwa wie folgt:

 Car.getFoo.toString() == "getFoo" // TRUE
24
drozzy

Da Methoden keine Objekte selbst sind, haben sie keine direkten Eigenschaften (wie Sie es von erstklassigen Funktionen in Sprachen wie JavaScript erwarten würden).

Am nächsten können Sie anrufen Car.class.getMethods()

Car.class ist ein Objekt Class , mit dem Sie eine der Reflexionsmethoden aufrufen können.

Eine Methode kann sich meines Wissens jedoch nicht identifizieren.

19
Matt

Sie können den String wie folgt erhalten:

Car.class.getDeclaredMethods()[0].getName();

Dies gilt für eine einzelne Methode in Ihrer Klasse. Wenn Sie alle deklarierten Methoden durchlaufen möchten, müssen Sie das von Car.class.getDeclaredMethods() zurückgegebene Array durchlaufen:

for (Method method : Car.class.getDeclaredMethods()) {
    String name = method.getName();
}

Sie sollten getDeclaredMethods() verwenden, wenn Sie alle anzeigen möchten. getMethods() gibt nur public Methods zurück.

Und schließlich, wenn Sie den Namen der Methode sehen möchten, die gerade ausgeführt wird, sollten Sie diesen Code verwenden:

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

Dadurch wird eine Stapelablaufverfolgung für den aktuellen Thread abgerufen und der Name der Methode wird oben angezeigt.

35
Malcolm

Sie möchten also den Namen der aktuell ausgeführten Methode ermitteln? Hier ist ein etwas hässlicher Weg, das zu tun:

Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();
14
Jesper

versuche dies,

 import Java.lang.reflect.*;
    public class DumpMethods {
        public static void main(String args[]) {
            try {
                Class c = Class.forName(args[0]);
                Method m[] = c.getDeclaredMethods();
                for (int i = 0; i < m.length; i++)
                    System.out.println(m[i].toString());
            } catch (Throwable e) {
                System.err.println(e);
            }
        }
    }
1
zhy2002

Mit Java 8 können Sie dies mit wenigen Zeilen Code (fast) ohne zusätzliche Bibliotheken tun. Der Schlüssel ist, Ihre Methode in einen serialisierbaren Lambda-Ausdruck zu konvertieren. Daher können Sie einfach eine einfache Schnittstelle wie folgt definieren:

@FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
  // Combined interface for Function and Serializable
}

Nun müssen wir unseren Lambda-Ausdruck in ein SerializedLambda-Objekt konvertieren. Anscheinend möchte Oracle nicht, dass wir das tun, also nehmen Sie dies mit einem Salzkorn ... Da die erforderliche Methode privat ist, müssen wir sie mit Reflexionen aufrufen:

private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
  Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
  findMethod.setAccessible(true);

  SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
  return invokeMethod.getImplMethodName();
}

Ich verwende hier die Springs ReflectionUtils-Klasse zur Vereinfachung. Sie können dies natürlich ersetzen, indem Sie alle Superklassen manuell durchlaufen und getDeclaredMethod verwenden, um die writeReplace-Methode zu finden.

Und das ist es schon, jetzt kannst du es so benutzen:

@Test
public void testNameOf() throws Throwable {
  assertEquals("getName", nameOf(MyClassTest::getName));
}

Ich habe dies nicht mit dem Java 9s-Modulsystem überprüft, daher kann es als kleiner Haftungsausschluss mit neueren Java-Versionen schwieriger sein ... 

0
Jan Gassen

Warten Sie, da Sie den Methodennamen bereits kennen, können Sie ihn nicht einfach als Zeichenfolge eingeben?

Anstelle von (Pseudo) Class.methodName.toString() verwenden Sie einfach "methodName ".

Ansonsten können Sie Class#getDeclaredMethods() verwenden, um alle Methoden in einer Klasse abzurufen

0
Bozho

Schau in diesen Thread:

Den Namen der aktuell ausgeführten Methode abrufen

Es bietet einige weitere Lösungen an, zum Beispiel:

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