【问题标题】:Get a class by name from stack trace从堆栈跟踪中按名称获取类
【发布时间】:2019-06-30 18:27:00
【问题描述】:

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

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

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

【问题讨论】:

  • MyObject.instanaceOf(Class.forName(className)) [原文如此] 不是您想要的:这是 obj instanceof MyObject 的动态等效项。如果您没有Class.forName(className) 的实例,则不会使用它。

标签: java stack-trace instanceof


【解决方案1】:

stacktrace 引用从初始线程调用的每个方法(class:method:line),直到您询问 stracktrace 的位置。
堆栈跟踪旨在了解执行了哪些代码/语句,而不知道调用该方法的运行时类(虽然在某些情况下您可能知道)。
事实上,你会知道被调用方法的运行时类,而它不是被继承的,或者是被继承但被覆盖的。
例如,如果您不覆盖 Foo 中的 toString()toString() 将在 stracktrace 中引用 Object.toString()

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    相关资源
    最近更新 更多