Java ou tout autre langage: Quelle méthode / classe a invoqué le mien?

Je voudrais écrire un code interne à ma méthode qui affiche quelle méthode / classe l’a appelée.

(Mon hypothèse est que je ne peux rien changer d’autre que ma méthode ..)

Qu’en est-il des autres langages de programmation?

EDIT: Merci les gars, qu’en est-il de JavaScript? python? C ++?

Ceci est spécifique à Java.

Vous pouvez utiliser Thread.currentThread(). getStackTrace() . Cela renverra un tableau de StackTraceElements .

Le 2ème élément du tableau sera la méthode d’appel.

Exemple:

 public void methodThatPrintsCaller() { StackTraceElement elem = Thread.currentThread.getStackTrace()[2]; System.out.println(elem); // rest of you code } 

Si vous souhaitez simplement imprimer la trace de la stack et rechercher le cours, utilisez

 Thread.dumpStack(); 

Voir la doc de l’ API .

Justin a le cas général bas; Je voulais mentionner deux cas spéciaux illustrés par cet extrait:

 import java.util.Comparator; public class WhoCalledMe { public static void main(Ssortingng[] args) { ((Comparator)(new SomeReifiedGeneric())).compare(null, null); new WhoCalledMe().new SomeInnerClass().someInnerMethod(); } public static StackTraceElement getCaller() { //since it's a library function we use 3 instead of 2 to ignore ourself return Thread.currentThread().getStackTrace()[3]; } private void somePrivateMethod() { System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller()); } private class SomeInnerClass { public void someInnerMethod() { somePrivateMethod(); } } } class SomeReifiedGeneric implements Comparator { public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) { System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller()); return 0; } } 

Cela imprime:

 SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1) somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14) 

Même si le premier est appelé “directement” par main() et le second par SomeInnerClass.someInnerMethod() . Dans ces deux cas, un appel transparent a été passé entre les deux méthodes.

  • Dans le premier cas, cela est dû au fait que nous appelons la méthode bridge à une méthode générique, ajoutée par le compilateur pour garantir que SomeReifiedGeneric puisse être utilisé comme type brut.
  • Dans le second cas, c’est parce que nous appelons un membre privé de WhoCalledMe à partir d’une classe interne. Pour ce faire, le compilateur ajoute une méthode synthétique comme intermédiaire pour résoudre les problèmes de visibilité.

la séquence d’appels de méthodes est située dans la stack. Voici comment obtenir la stack: Obtenir la trace de la stack actuelle en Java, puis obtenir l’élément précédent.

Comme vous avez demandé d’autres langues, Tcl vous donne une commande ( niveau d’information ) qui vous permet d’examiner la stack d’appels. Par exemple, [info level -1] renvoie l’appelant de la procédure en cours, ainsi que les arguments utilisés pour appeler la procédure en cours.

En Python, vous utilisez le module inspecter . Obtenir le nom de la fonction et le nom du fichier est facile, comme vous le voyez dans l’exemple ci-dessous.

Obtenir la fonction elle-même est plus de travail. Je pense que vous pourriez utiliser la fonction __import__ pour importer le module de l’appelant. Cependant, vous devez en quelque sorte convertir le nom de fichier en un nom de module valide.

 import inspect def find_caller(): caller_frame = inspect.currentframe().f_back print "Called by function:", caller_frame.f_code.co_name print "In file :", caller_frame.f_code.co_filename #Alternative, probably more portable way #print inspect.getframeinfo(caller_frame) def foo(): find_caller() foo() 

Oui c’est possible.

Jetez un coup d’œil à Thread.getStackTrace ()

En Python, vous devez utiliser les modules traceback ou inspect. Ces modules testament vous protégeront des détails de mise en œuvre de l’interpréteur, qui peuvent différer encore aujourd’hui (par exemple, IronPython, Jython) et peuvent changer encore plus à l’avenir. Cependant, la manière dont ces modules fonctionnent sous l’interpréteur Python standard actuel est avec sys._getframe (). En particulier, sys._getframe (1) .f_code.co_name fournit les informations souhaitées.