从堆栈跟踪中按名称获取课程

时间:2019-06-30 18:27:00

标签: java stack-trace instanceof

在一个类中,我试图通过使用线程的堆栈跟踪来确定谁最初调用了调用链:

StackTraceElement trace = Thread.getStackTrace();
for (int index = 3; index < trace.length; index++ ) {
    String className = trace[index].getClassName();

现在,我知道该调用将始终由超类型MyObject发起,但是我想知道哪个子类实际上是出于日志记录/审核目的而启动该调用的。

我首先尝试看看我是否可以在逻辑上匹配超类,但是即使那样也失败了;我已经尝试了以下所有4种方法,但它们似乎都返回false:

通过单步执行,我可以看到我正在使用正确的 className 循环,这是我的孩子扩展了MyObject

    if (Class.forName(className).isAssignableFrom(MyObject.class)) {
    if (MyObject.isAssignableFrom(Class.forName(className))) {

    if (Class.forName(className).instanaceOf(MyObject.class)) {
    if (MyObject.instanaceOf(Class.forName(className))) {

我还能如何测试我拥有的类名是否扩展了某个父级?

1 个答案:

答案 0 :(得分:3)

stacktrace引用从初始线程一直调用到您询问stracktrace的位置的每个方法(类:方法:行)。
stacktrace旨在了解执行了哪些代码/语句,并且不知道调用该方法的运行时类(尽管在某些情况下您可能会知道)。
实际上,您将知道被调用方法未继承或被继承但被覆盖时的运行时类。
例如,如果您没有在Foo中覆盖toString(),则toString()将在stracktrace中引用Object.toString()

因此,为了以实际方式满足您的要求,您需要覆盖要审核的类的入口点,然后调用super.theMethod()
但是更干净的方法可能是使用AOP(AspectJ或Spring AOP)来捕获您将利用的任何信息。例如,在审核入口点方法方面,您可以使用getClass()来了解对象的类型。