Czy istnieje sposób na uzyskanie nazwy aktualnie wykonywanej metody w Javie?
java
reflection
methods
Omar Kooheji
źródło
źródło
Technicznie to zadziała ...
Jednak nowa anonimowa klasa wewnętrzna zostanie utworzona podczas kompilacji (np
YourClass$1.class
.). Spowoduje to utworzenie.class
pliku dla każdej metody wdrażającej tę sztuczkę. Dodatkowo przy każdym wywołaniu tworzona jest instancja nieużywanego obiektu w czasie wykonywania. Może to być dopuszczalna sztuczka debugowania, ale wiąże się to ze znacznym nakładem pracy.Zaletą tej sztuczki jest to, że
getEncosingMethod()
zwrotyjava.lang.reflect.Method
można wykorzystać do pobrania wszystkich innych informacji o metodzie, w tym adnotacji i nazw parametrów. Umożliwia to rozróżnienie konkretnych metod o tej samej nazwie (przeciążenie metody).Zauważ, że zgodnie z JavaDoc
getEnclosingMethod()
tej sztuczki nie należy rzucać,SecurityException
ponieważ klasy wewnętrzne powinny być ładowane przy użyciu tego samego modułu ładującego klasy. Nie ma więc potrzeby sprawdzania warunków dostępu, nawet jeśli obecny jest menedżer bezpieczeństwa.Wymagane jest użycie
getEnclosingConstructor()
dla konstruktorów. Podczas bloków poza (nazwanymi) metodamigetEnclosingMethod()
zwracanull
.źródło
getEnclosingMethod
pobiera nazwę metody, w której klasa jest zdefiniowana.this.getClass()
w ogóle ci nie pomoże. @wutzebaer, dlaczego miałbyś to robić? Masz już do nich dostęp.Styczeń 2009:
Pełny kod będzie (do użycia z zastrzeżeniem @ Bombe ):
Więcej w tym pytaniu .
Aktualizacja z grudnia 2011 r .:
niebieskawy komentarze:
virgo47 „s odpowiedź (upvoted) rzeczywiście oblicza indeks prawo do zastosowania w celu uzyskania z powrotem nazwę metody.
źródło
StackTraceElement
tablicę w celu debugowania i sprawdzić, czy 'main' jest rzeczywiście właściwą metodą?ste[2 + depth].getMethodName()
. 0 oznaczagetStackTrace()
, 1 oznacza,getMethodName(int depth)
a 2 wywołuje metodę. Zobacz także odpowiedź @ virgo47 .Użyliśmy tego kodu, aby ograniczyć potencjalną zmienność indeksu śledzenia stosu - teraz wystarczy wywołać metodę methodName
Wydaje się, że mamy nadmiar inżynierii, ale mieliśmy pewną stałą liczbę dla JDK 1.5 i byliśmy nieco zaskoczeni, że zmieniło się, kiedy przeszliśmy na JDK 1.6. Teraz jest tak samo w Javie 6/7, ale nigdy nie wiadomo. Nie świadczy to o zmianach tego indeksu w czasie wykonywania - ale mam nadzieję, że HotSpot nie robi tak źle. :-)
źródło
nazwa będzie miała wartość foo.
źródło
null
Obie te opcje działają dla mnie w Javie:
Lub:
źródło
Najszybciej odkryłem, że:
Uzyskuje bezpośredni dostęp do natywnej metody getStackTraceElement (int depth). I przechowuje dostępną metodę w zmiennej statycznej.
źródło
new Throwable().getStackTrace()
zajęło 5614 ms.Użyj następującego kodu:
źródło
źródło
Jest to rozszerzenie odpowiedzi virgo47 (powyżej).
Zapewnia niektóre metody statyczne, aby uzyskać bieżące i wywołujące nazwy klas / metod.
źródło
Aby uzyskać nazwę metody, która wywołała bieżącą metodę, możesz użyć:
Działa to na moim MacBooku, a także na telefonie z Androidem
Próbowałem także:
ale Android zwróci „getStackTrace”. Mogę to naprawić dla Androida
ale potem otrzymuję złą odpowiedź na moim MacBooku
źródło
getStackTrace()[0]
, niżgetStackTrace()[1]
. YMMV.Thread.currentThread().getStackTrace()[2]
Util.java:
SomeClass.java:
źródło
final StackTraceElement e = Thread.currentThread().getStackTrace()[2];
Pracuje;e.getClassName();
zwraca pełną nazwę klasy ie.getMethodName()
zwraca nazwę methon.getStackTrace()[2]
jest źle, musi być tak,getStackTrace()[3]
ponieważ: [0] dalvik.system.VMStack.getThreadStackTrace [1] java.lang.Thread.getStackTrace [2] Utils.getCurrentClassAndMethodNames [3] Funkcja a () wywołująca tęMożna to zrobić za pomocą
StackWalker
Java 9.StackWalker
jest zaprojektowany tak, aby był leniwy, więc może być bardziej wydajny niż, powiedzmy,Thread.getStackTrace
który chętnie tworzy tablicę dla całego zestawu wywołań. Zobacz także JEP, aby uzyskać więcej informacji.źródło
Alternatywną metodą jest utworzenie, ale nie zgłoszenie wyjątku, i użycie tego obiektu, z którego można pobrać dane śledzenia stosu, ponieważ metoda zamykająca zwykle ma indeks 0 - o ile JVM przechowuje te informacje, tak jak inni wspomniano powyżej. Nie jest to jednak najtańsza metoda.
Od Throwable.getStackTrace () (było tak samo od co najmniej Java 5):
Poniższy fragment zakłada, że klasa jest niestatyczna (z powodu getClass ()), ale to na bok.
źródło
źródło
Mam rozwiązanie korzystające z tego (w Androidzie)
źródło
Nie wiem, jaki jest zamiar uzyskania nazwy obecnie wykonywanej metody, ale jeśli jest to tylko w celu debugowania, struktury rejestrowania takie jak „logback” mogą tutaj pomóc. Na przykład w logback wszystko, co musisz zrobić, to użyć wzorca „% M” w konfiguracji logowania . Należy jednak zachować ostrożność, ponieważ może to obniżyć wydajność.
źródło
Na wypadek, gdyby metoda, którą chcesz znać, jest metodą testową junit, możesz użyć reguły junit TestName: https://stackoverflow.com/a/1426730/3076107
źródło
Większość odpowiedzi tutaj wydaje się błędna.
Przykład:
Wyjścia:
źródło
Przepisałem trochę odpowiedź maklemenz :
źródło
źródło
getEnclosingMethod()
rzucaNullPointerException
dla mnie w Javie 7.Co jest złego w tym podejściu:
I zanim ludzie oszaleją na temat używania
System.out.println(...)
, zawsze możesz i powinieneś stworzyć jakąś metodę, aby dane wyjściowe mogły zostać przekierowane, np .:źródło