在一个类中,我尝试使用线程的堆栈跟踪来确定谁最初调用了调用链:
StackTraceElement trace = Thread.getStackTrace();
for (int index = 3; index < trace.length; index++ ) {
String className = trace[index].getClassName();
现在我知道调用始终由 super 类型 MyObject
发起,但我想知道哪个子类实际上出于日志记录/审核目的启动了调用。
我首先尝试看看我是否可以在逻辑上匹配父类(super class),但即使这样也失败了;我已经尝试了以下所有 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))) {
我还能如何测试我所拥有的类名是否扩展了某个父类?
最佳答案
堆栈跟踪引用从初始线程调用的每个方法(类:方法:行),直到您询问堆栈跟踪的位置。
堆栈跟踪旨在了解执行了哪些代码/语句,而不是了解调用该方法的运行时类(尽管在某些情况下您可能知道它)。
事实上,当调用的方法没有被继承或者被继承但被重写时,您会知道它的运行时类。
例如,如果您不重写 Foo 中的 toString()
,则 toString()
将引用 stracktrace 中的 Object.toString()
。
因此,要以实际方式实现您的要求,您需要重写要审核的类的入口点,然后调用 super.theMethod()
。
但更简洁的方法可能是使用 AOP(AspectJ 或 Spring AOP)来捕获您要利用的任何信息。例如,在审计入口点方法方面,您可以使用getClass()
来了解对象的类型。
关于java - 从堆栈跟踪中按名称获取类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56827124/