
Tom
In Java ist es möglich, die Klasse und Methode abzurufen, die die aktuelle Methode aufgerufen haben (die Methode, in der Sie den StackTrace erhalten).
Kann ich die Argumente abrufen, die an die Methode übergeben wurden, die diese Methode aufgerufen hat?
Ich brauche dies für Debugging-Zwecke.
Z.B:
baseClass {
initialFunc(input) {
var modifiedInput = input + " I modified you";
otherClass.doSomething(modifiedInput);
}
}
otherClass {
doSomething(input) {
//GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
}
}
Kann man diese Informationen aus dem Stacktrace bekommen, oder gibt es andere Mittel?
(Beachten Sie, dass ich dies zur Laufzeit tun muss und die Quelle von baseClass nicht wirklich ändern kann. Dies wird eine Funktion meiner Debugging-Klasse sein, die die Quelle vorher nicht kennt.)
Ich glaube nicht, dass dies mit der Standard-Java-API möglich ist.
Was Sie tun könnten, ist, AspectJ zu verwenden, einen Point-Cut an der aufrufenden Methode zu platzieren, die Argumente zu speichern, einen Point-Cut an der aufgerufenen Methode zu platzieren und die Argumente weiterzugeben.
Eine andere (etwas fortgeschrittenere) Option besteht darin, einen benutzerdefinierten, den Bytecode umschreibenden Klassenlader zu verwenden, der die ursprünglichen Argumente speichert und sie als zusätzliche Argumente an die nächste Methode weiterleitet. Dies würde wahrscheinlich ein oder zwei Tage dauern, um es umzusetzen. Geeignete Frameworks sind BCEL oder ASM.

Christoph Klewes
Ich denke, das könnte möglich sein, weil input
liegt außerhalb des Gültigkeitsbereichs, ist aber noch nicht für die Garbage Collection zugänglich, daher ist der Wert noch vorhanden, aber leider glaube ich nicht, dass es eine Standard-API-Methode gibt, um darauf zuzugreifen. Dies könnte möglicherweise mit einem benutzerdefinierten implementierten NDC möglich sein (verschachtelter diagnostischer Kontext) für den Logging-Ansatz.
Ich bin mir nicht sicher, warum Sie dies jemals in Java tun möchten?
Die einzige Möglichkeit, die mir einfällt, besteht darin, ein benutzerdefiniertes Wrapper-Objekt für die übergebene Zeichenfolge zu erstellen und so die Referenz jedes Mal anstelle einer neuen Zeichenfolge an den Wrapper zu senden.
Ich würde jedoch davon abraten, da es Ihren ursprünglichen Code unübersichtlich macht und ihn noch fehleranfälliger macht.
Könnte dieses Problem nicht mit einem Debugger, wie dem in Eclipse integrierten, gelöst werden, um Ihren Zustand zu überprüfen?
In meinem Fall musste ich einen Parameterwert abrufen, der an eine Methode in einem bestimmten Stapelrahmen übergeben wurde, um später im Ausführungsablauf verwendet zu werden
ich benutzte ThreadLocal
um es zu speichern, und wenn ich es brauchte, konnte ich es an jedem Punkt im Code abrufen, wie ich es deklariert hatte public static
Hier ist ein Skelettbeispiel
public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);
methodWithImportantParam(SomeType importantValue){
// save it in the static threadLocal Field
this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
// continue method logic
}
und irgendwo im Code, wo Sie diesen Wert benötigen
YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()
Stellen Sie jedoch sicher, dass der Ausführungsfluss den Wert festlegt, und rufen Sie ihn dann ab
Ich hoffe, meine Antwort fügt dieser Frage etwas Wertvolles hinzu
Sie können den Namen der aufrufenden Methode und ihrer Klasse abrufen, aber Sie müssen der aktuellen Methode etwas Code hinzufügen:
public static void main(String[] args) throws Exception {
call();
}
private static void call() {
Exception exception = new Exception();
for(StackTraceElement trace : exception.getStackTrace()){
System.out.println(trace.getMethodName());
}
}
Dadurch werden “call” und “main”, Methodennamen in aufgerufener Reihenfolge (umgekehrt) ausgegeben.

Kev
Dies ist mit der Reflection-API möglich!
public class StackTrace {
public static void main(String args[]) {
StackTrace st = new StackTrace();
st.func();
}
public void func() {
OtherClass os =new OtherClass();
os.getStackTrace(this);
}
}
class OtherClass {
void getStackTrace(Object obj) {
System.out.println(obj.getClass());
}
}
10168200cookie-checkWie werden Argumente an die Methode übergeben, die diese Methode aufgerufen hat?yes
Sie können, wenn Sie einen Debugger anhängen, sonst – nein. Die Parameter befinden sich möglicherweise in CPU-Registern (nicht auf dem Stack).
– bestes
9. Februar 2011 um 10:38 Uhr
Ich fürchte, ich kann für meine Zwecke keinen Debugger anhängen
– Tom
9. Februar 2011 um 10:39 Uhr
Dann sind Sie verloren, abgesehen von ClassLoader und der Erweiterung der Klasse im laufenden Betrieb, um die Argumente abzufangen. (aber du würdest nicht fragen, ob du wüsstest wie)
– bestes
9. Februar 2011 um 10:42 Uhr
Wenn ein Debugger das kann, dann muss es irgendwie möglich sein. AFAIK, ein Debugger verwendet keine Code-Instrumentierung oder ähnliches, da er an jeden Java-Prozess angehängt werden kann. Keine Ahnung, wie das funktioniert, vielleicht etwas JMX?
– maaartinus
9. Februar 2011 um 10:54 Uhr
@bestsss, das führte mich zu einer Folgefrage: stackoverflow.com/questions/4945358/… – Ich habe diese Frage akzeptiert.
– Tom
9. Februar 2011 um 13:17 Uhr