Java 从堆栈跟踪元素获取实际类

Java 从堆栈跟踪元素获取实际类,java,debugging,reflection,stack-trace,Java,Debugging,Reflection,Stack Trace,使用Eclipse,我可以设置断点并在调试视图上查看当前堆栈跟踪: 但是当我使用Thread.currentThread().getStackTrace()检查堆栈跟踪时,我得到的信息并不完全相同。例如,所选元素是junitsetclassreference,堆栈跟踪中的相关元素(在破折号内)是JUnit4TestReference(它的超类,可能是因为run方法没有被子类覆盖) 有没有办法获得子类名称 如果没有,Eclipse是如何获得它的(可能是使用的) StackTraceeEleme

使用Eclipse,我可以设置断点并在调试视图上查看当前堆栈跟踪:

但是当我使用
Thread.currentThread().getStackTrace()
检查堆栈跟踪时,我得到的信息并不完全相同。例如,所选元素是
junitsetclassreference
,堆栈跟踪中的相关元素(在破折号内)是
JUnit4TestReference
(它的超类,可能是因为
run
方法没有被子类覆盖)

  • 有没有办法获得子类名称
  • 如果没有,Eclipse是如何获得它的(可能是使用的)

StackTraceeElement
不包含对所涉及的实际对象的引用,只包含对类的引用。我可以想出许多理由来解释为什么这实际上是一个好主意,尤其是
StackTraceElement
的可序列化性

stackTraceeElement
中的类引用被定义为引用声明方法的类,而不是在异常发生时保存方法的当前对象的类。这可能是为了让您能够区分超级实现和重写实现。因此,只有异常后堆栈跟踪,实际对象和实际子类都无法获得(更多)

Eclipse(和其他调试器接口)显示程序运行时的实时跟踪。您正确地注意到,此实时信息是通过JPDA获得的

Java调试接口(JDI)可以访问表示为的实时堆栈帧信息,其中实际对象可用:

ObjectReference thisObject()
返回当前帧的“this”值。“this”的ObjectReference仅适用于非本机实例方法


堆栈记录哪些代码正在等待调用返回,而不是哪些对象。如果方法在超类中,而子类没有覆盖它,堆栈将记录超类方法,,因为控制最终必须在那里返回

获取所涉及对象的运行时类的唯一方法是检查激活框架中对方法的特定调用的
this
引用的值。调试器可以向您展示这一点,但要从Java本身获得这一点,并没有真正简单的方法,您必须对JDI之类的接口进行调试


请注意,还有另一个挑战:报告类名称,而不是类对象。由于
ClassLoader
s的工作方式,同一个VM中可能有两个类具有相同的名称,
StackTraceElement
没有提供足够的信息来区分它们。(这就是像Tomcat这样的容器如何为同一个VM中的两个不同应用程序加载同一库的两个不同版本。)

也许这会有助于将来的参考,因为我遇到了同样的问题,并且想知道如何做到这一点

您可以使用以下方法从
StackTraceeElement
获取方法对象:

//替换为StackTraceElement
StackTraceElement方法\u obj=Thread.currentThread().getStackTrace()[0]
Class object\u context=Class.forName(方法\u obj.className)
Method Method=object\u context.getMethod(Method\u obj.methodName,null)
ObjectReference thisObject()