2011-07-14 5 views
9

Zasadniczo mam instrukcja rejestrowania wewnątrz metody. Za każdym razem, gdy wywoływana jest metoda, chcę łatwo wywołać nazwę metody i dołączyć ją do instrukcji rejestrowania. Ma to na celu zminimalizowanie liczby zakodowanych linii w mojej aplikacji. Czy można to zrobić tanio?Czy mogę tanio wywołać metodę Java, aby uzyskać nazwę bieżącej metody?

+1

Nie sądzę, że istnieje dobra metoda, która może być użyta w środowisku wykonawczym do tego, ale prawdopodobnie można opisać metody wymagające tej funkcji, a następnie napisać procesor adnotacji, który zostanie włączony do procesu kompilacji. W środowisku uruchomieniowym działałoby prawie identycznie jak w przypadku twardego kodowania nazwy metody, ale nie musiałbyś w rzeczywistości niczego kodować. –

+0

prawdopodobny duplikat [Uzyskiwanie nazwy obecnej metody wykonywania] (http://stackoverflow.com/questions/442747/getting-nazwa-tworzenia-przeszłego-wykonywania-modelu) – bmargulies

Odpowiedz

15

Nie, nie tanio. Jedynym drogim i jedynym sposobem na to jest wywołanie metody StackTrace. Najlepiej po prostu go zakodować.

+0

Cóż, szkoda. Nie wiem, dlaczego java nie może jeszcze tego zrobić tanio. –

+0

AspectJ został zaprojektowany, aby poradzić sobie z takimi problemami. – antlersoft

+0

Jak używać AspectJ do robienia czegoś takiego? Najbliższa metoda jaką mogę znaleźć to "getSourceMethod()" –

3

Jeśli potrzebujesz tylko nazwy metody i numeru linii, możesz zrobić to w miarę szybko. W moim mikro odniesienia można zrobić około 120.000 połączeń na sekundę

public class A { 
    private static final int N = 1000000; 

    public static void main(String[] args) { 
    A a = new A(); 
    long l = System.currentTimeMillis(); 
    for (int i = 0; i < N; i++) { 
     a.test(0); 
     a.test(1); 
     a.test(2); 
    } 
    double time = (System.currentTimeMillis() - l)/1000d; 
    System.err.println(time + " seconds"); 
    System.err.println(N/time + " calls/second"); 
    } 

    String test(int i) { 
    StackTraceElement ste = Thread.currentThread().getStackTrace()[i]; 
    return ste.getMethodName() + ":" + ste.getLineNumber(); 
    } 
} 

Zobacz również this answer.

+0

'Test łańcuchowy (int i) { StackTraceElement ste = Thread.currentThread(). getStackTrace() [i]; // String aString = "bleh"; // return aString; powrót ste.getMethodName(); } } 'Pobiegłem testowanie między robi twardą kod i robi StackTrace // Z StackTrace // 30.281 sekund //33024.00845414616 połączeń/sekundę // drugim przejeździe //17.937 sekund // 55750 Połączenia/sekundę // Z twardym ciągiem //0.016 sekund //6.25E7 połączeń/sekunda --- Zasadniczo znaczny 100-krotny wzrost kosztów w porównaniu do powrotu kodu sztywnego – TravMan

+0

Dobrze. Wszystko zależy jednak od tego, jak często ten kod jest wywoływany. Powiedz, jeśli zadzwonisz na nią tylko raz na sekundę, może naprawdę możesz sobie na to pozwolić. –

+0

Co z adnotacją lub czymś, co po prostu nagrywa bieżącą nazwę metody, więc mogę wyciąć wklejkę bez zmieniania głupiego łańcucha w kółko? – ggb667

2

Dlaczego wyważać otwartych drzwi, java.util.logging.Logger wykorzystuje

/** 
* Gets the StackTraceElement of the first class that is not this class. 
* That should be the initial caller of a logging method. 
* @return caller of the initial logging method or null if unknown. 
*/ 
private StackTraceElement getCallerStackFrame() 
{ 
Throwable t = new Throwable(); 
StackTraceElement[] stackTrace = t.getStackTrace(); 
int index = 0; 

// skip to stackentries until this class 
while(index < stackTrace.length 
    && !stackTrace[index].getClassName().equals(getClass().getName())) 
    index++; 

// skip the stackentries of this class 
while(index < stackTrace.length 
    && stackTrace[index].getClassName().equals(getClass().getName())) 
    index++; 

    return index < stackTrace.length ? stackTrace[index] : null; 
} 

wątpię, otrzymasz go szybciej niż ten.

[Edytuj] Aby uzyskać metodami telefoniczne Nazwa Użyj,

StackTraceElement caller = getCallerStackFrame(); 
String name = caller != null ? caller.getMethodName() : "<unknown>" 
+0

To wykorzystuje StackTrace i wymaga użycia logger Java. To dobrze, jeśli testujesz w małej aplikacji w domu, ale jak na przebieg testu poniżej StackTrace jest 100 razy wolniejszy. – TravMan

+0

@ TravMan Zgadzam się, po prostu poprosił o zewnętrzną metodę, którą mógłby nazwać, która zwróci nazwę metody dzwoniącego, z pominięciem twardego kodowania nazwy (i pozornie [wooo złego]), ta metoda byłaby najszybsza. 100 razy nie ma ramki odniesienia i wyobrażam sobie, że to wszystko jest dyskusyjne i ścigamy czarodziejską mikrooptymalizację. – Andrew

+0

również przegłosowano, nigdy nie używałam takiej klasy Logger – TravMan

1

pan rozważyć pisanie sensownych wiadomości dziennika zamiast? Mam na myśli wiadomości, które po prostu mówią czytelnikowi, żeby zapisał "historię" o tym, jak działa kod? wiadomości, które naprawdę różnią się dla różnych metod?

log4j: some.package.Class1: method1: checkpoint #1 
    log4j: some.package.Class1: method1: checkpoint #2 
    log4j: some.package.Class2: method2: checkpoint #1 
    log4j: some.package.Class2: method2: checkpoint #2 

Uderzyłem głową w dziennik jak powyżej zaledwie tydzień lub dwa lata temu (nazwy metod zostały ustalone na stałe). Nie wydawało się to zauważalnie bardziej pomocne niż brak logowania.

Powiązane problemy