Java or any other language: Which method/class invoked mine?
我想在我的方法内部编写一个代码,用于打印哪个方法/类调用它。
(我的假设是我不能改变任何东西,除了我的方法..)
其他编程语言怎么样?
编辑:谢谢你们,JavaScript怎么样? Python?C ++?
这是Java特有的。
您可以使用
数组中的第二个元素是调用方法。
例:
1 2 3 4 5 6 |
贾斯汀的情况有所下降;我想提一下这个snippit演示的两个特例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import java.util.Comparator; public class WhoCalledMe { public static void main(String[] 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<SomeReifiedGeneric> { public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) { System.out.println("SomeRefiedGeneric.compare() called by:" + WhoCalledMe.getCaller()); return 0; } } |
这打印:
1 2 | SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1) somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14) |
即使第一个被称为"直接"来自
- 在第一种情况下,这是因为我们将bridge方法调用为泛型方法,由编译器添加以确保SomeReifiedGeneric可以用作原始类型。
- 在第二种情况下,这是因为我们从内部类调用WhoCalledMe的私有成员。为此,编译器添加了一个合成方法作为覆盖可见性问题的中间人。
如果您只想打印堆栈跟踪并去寻找课程,请使用
1 |
请参阅API文档。
方法调用的顺序位于堆栈中。这就是你如何获得堆栈:在Java中获取当前堆栈跟踪然后获取上一个项目。
在Python中,您使用inspect模块。
获取函数的名称和文件名很简单,如下例所示。
获得功能本身就更有效。我想你可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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() |
由于您询问了其他语言,Tcl为您提供了一个命令(信息级别),可以让您检查调用堆栈。例如,
在Python中,您应该使用traceback或inspect模块。这些模块将保护您免受解释器的实现细节的影响,即使在今天(例如IronPython,Jython)也可能有所不同,并且将来可能会发生更多变化。然而,这些模块在今天使用标准Python解释器执行此操作的方式是使用sys._getframe()。特别是,sys._getframe(1).f_code.co_name提供了所需的信息。
对的,这是可能的。
看一下Thread.getStackTrace()