Java 或任何其他语言:哪个方法/类调用了我的?

发布于 2024-09-14 17:22:42 字数 153 浏览 3 评论 0 原文

我想在我的方法内部编写一个代码来打印哪个方法/类调用了它。

(我的假设是除了我的方法之外我不能改变任何东西。)

其他编程语言怎么样?

编辑:谢谢大家,JavaScript 怎么样? Python? C++?

I would like to write a code internal to my method that print which method/class has invoked it.

(My assumption is that I can't change anything but my method..)

How about other programming languages?

EDIT: Thanks guys, how about JavaScript? python? C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

御守 2024-09-21 17:22:42

这是 Java 特有的。

您可以使用 Thread.currentThread()。 getStackTrace()。这将返回 StackTraceElements

数组中的第二个元素将是调用方法。

例子:

public void methodThatPrintsCaller() {
    StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
    System.out.println(elem);

    // rest of you code
}

This is specific to Java.

You can use Thread.currentThread().getStackTrace(). This will return an array of StackTraceElements.

The 2nd element in the array will be the calling method.

Example:

public void methodThatPrintsCaller() {
    StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
    System.out.println(elem);

    // rest of you code
}
紫罗兰の梦幻 2024-09-21 17:22:42

如果您只想打印堆栈跟踪并寻找该类,请使用

Thread.dumpStack();

请参阅 API 文档

If all you want to do is print out the stack trace and go hunting for the class, use

Thread.dumpStack();

See the API doc.

静水深流 2024-09-21 17:22:42

贾斯汀已经掌握了一般情况;我想提一下此片段演示的两个特殊情况:

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;
    }
}

此打印:

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

即使第一个是从 main() 中“直接”调用的,第二个是从 SomeInnerClass.someInnerMethod() 中调用的>。这是两个方法之间进行透明调用的两种情况。

  • 在第一种情况下,这是因为我们正在调用 桥接方法到由编译器添加的泛型方法,以确保 SomeReifiedGeneric 可以用作原始类型。
  • 在第二种情况下,这是因为我们从内部类调用 WhoCalledMe 的私有成员。为了实现这一点,编译器添加了一个合成方法作为中间人来覆盖可见性问题。

Justin has the general case down; I wanted to mention two special cases demonstrated by this snippit:

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;
    }
}

This prints:

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

Even though the first is called "directly" from main() and the second from SomeInnerClass.someInnerMethod(). These are two cases where there is a transparent call made in between the two methods.

  • In the first case, this is because we are calling the bridge method to a generic method, added by the compiler to ensure SomeReifiedGeneric can be used as a raw type.
  • In the second case, it is because we are calling a private member of WhoCalledMe from an inner class. To accomplish this, the compiler adds a synthetic method as a go-between to override the visibility problems.
痕至 2024-09-21 17:22:42

方法调用的顺序位于堆栈中。这就是获取堆栈的方式: 获取 Java 中的当前堆栈跟踪 然后获取上一项。

the sequence of method calls is located in stack. this is how you get the stack: Get current stack trace in Java then get previous item.

巨坚强 2024-09-21 17:22:42

Since you asked about other languages, Tcl gives you a command (info level) that lets you examine the call stack. For example, [info level -1] returns the caller of the current procedure, as well as the arguments used to call the current procedure.

闻呓 2024-09-21 17:22:42

在 Python 中,您使用 inspect 模块。
获取函数的名称和文件名很容易,如下面的示例所示。

获取函数本身需要更多工作。我认为你可以使用 __import__ 函数导入调用者的模块。但是,您必须以某种方式将文件名转换为有效的模块名称。

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()

In Python you use the inspect module.
Getting the function's name and file name is easy, as you see in the example below.

Getting the function itself is more work. I think you could use the __import__ function to import the caller's module. However you must somehow convert the filename to a valid module name.

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()
夏至、离别 2024-09-21 17:22:42

是的,这是可能的。

看一下 Thread.getStackTrace()

Yes, it is possible.

Have a look at Thread.getStackTrace()

不…忘初心 2024-09-21 17:22:42

在 Python 中,您应该使用回溯或检查模块。这些模块将使您免受解释器的实现细节的影响,这些细节即使在今天也可能有所不同(例如 IronPython、Jython),并且将来可能会发生更多变化。然而,这些模块在今天的标准 Python 解释器下执行此操作的方式是使用 sys._getframe()。特别是,sys._getframe(1).f_code.co_name 提供了您想要的信息。

In Python, you should use the traceback or inspect modules. These will modules will shield you from the implementation details of the interpreter, which can differ even today (e.g. IronPython, Jython) and may change even more in the future. The way these modules do it under the standard Python interpreter today, however, is with sys._getframe(). In particular, sys._getframe(1).f_code.co_name provides the information you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文