从堆栈跟踪元素中获取实际 class
Get actual class from stack trace element
我可以使用 Eclipse 设置断点并在调试视图中查看当前堆栈跟踪:
但是当我使用 Thread.currentThread().getStackTrace()
检查堆栈跟踪时,我得到的信息并不完全相同。例如,所选元素是 JUnitTestClassReference
,堆栈跟踪中的相关元素(破折号内)是 JUnit4TestReference
(它的超类,可能是因为 run
方法未被子类覆盖)。
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks
org.junit.runners.ParentRunner
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
---- org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference ----
org.eclipse.jdt.internal.junit.runner.TestExecution
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
- 有什么方法可以得到子类名吗?
- 如果没有,Eclipse 是如何获取它的(可能使用 JPDA)?
StackTraceElement
不包含对所涉及的实际对象的引用,仅包含对 class 的引用。我可以想到为什么这实际上是一个好主意的许多原因,尤其是 StackTraceElement
.
的所有可序列化性
StackTraceElement
中的 class 引用被定义为引用 class 声明 方法,而不是 class发生异常时持有该方法的当前对象。这可能是为了区分超级实现和覆盖实现。因此,只有 post-exception 堆栈跟踪,实际对象和实际子 class 都无法(再)获得。
Eclipse(和其他调试器界面)向您显示程序的实时跟踪 运行。您正确地注意到此实时信息是通过 JPDA 获得的。
Java 调试接口 (JDI) 可以访问表示为 StackFrame
的实时堆栈帧信息,其中实际对象可用:
ObjectReference thisObject()
Returns the value of 'this' for the current frame. The ObjectReference for 'this' is only available for non-native instance methods.
堆栈记录 code 正在等待调用 return,而不是 objects。如果该方法在superclass中,而subclass没有覆盖它,堆栈将记录superclass方法,因为那是控制最终必须的地方return到.
在运行时 class 获取所涉及对象的唯一方法是检查激活帧中针对特定方法调用的 this
引用的值。调试器可以告诉你,但是没有真正简单的方法从 Java 本身得到它,你必须使用像 JDI 这样的调试接口。
请注意还有另一个挑战:StackTraceElement
报告了一个 class name,而不是 class object。由于 ClassLoader
的工作方式,同一 VM 中可能有两个同名的 class,而 StackTraceElement
无法提供足够的信息来区分它们. (这就是像 Tomcat 这样的容器可以为同一 VM 中的两个不同应用程序加载同一库的两个不同版本的方式。)
也许这有助于将来参考,因为我遇到了同样的问题,并且想知道如何做到这一点
您可以使用 StackTraceElement
从 StackTraceElement
获取方法对象:
//replace with your StackTraceElement
StackTraceElement method_obj = Thread.currentThread().getStackTrace()[0]
Class<?> object_context = Class.forName(method_obj.className)
Method method = object_context.getMethod(method_obj.methodName, null)
我可以使用 Eclipse 设置断点并在调试视图中查看当前堆栈跟踪:
但是当我使用 Thread.currentThread().getStackTrace()
检查堆栈跟踪时,我得到的信息并不完全相同。例如,所选元素是 JUnitTestClassReference
,堆栈跟踪中的相关元素(破折号内)是 JUnit4TestReference
(它的超类,可能是因为 run
方法未被子类覆盖)。
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.junit.runners.ParentRunner
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks
org.junit.runners.ParentRunner
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
---- org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference ----
org.eclipse.jdt.internal.junit.runner.TestExecution
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
- 有什么方法可以得到子类名吗?
- 如果没有,Eclipse 是如何获取它的(可能使用 JPDA)?
StackTraceElement
不包含对所涉及的实际对象的引用,仅包含对 class 的引用。我可以想到为什么这实际上是一个好主意的许多原因,尤其是 StackTraceElement
.
StackTraceElement
中的 class 引用被定义为引用 class 声明 方法,而不是 class发生异常时持有该方法的当前对象。这可能是为了区分超级实现和覆盖实现。因此,只有 post-exception 堆栈跟踪,实际对象和实际子 class 都无法(再)获得。
Eclipse(和其他调试器界面)向您显示程序的实时跟踪 运行。您正确地注意到此实时信息是通过 JPDA 获得的。
Java 调试接口 (JDI) 可以访问表示为 StackFrame
的实时堆栈帧信息,其中实际对象可用:
ObjectReference thisObject()
Returns the value of 'this' for the current frame. The ObjectReference for 'this' is only available for non-native instance methods.
堆栈记录 code 正在等待调用 return,而不是 objects。如果该方法在superclass中,而subclass没有覆盖它,堆栈将记录superclass方法,因为那是控制最终必须的地方return到.
在运行时 class 获取所涉及对象的唯一方法是检查激活帧中针对特定方法调用的 this
引用的值。调试器可以告诉你,但是没有真正简单的方法从 Java 本身得到它,你必须使用像 JDI 这样的调试接口。
请注意还有另一个挑战:StackTraceElement
报告了一个 class name,而不是 class object。由于 ClassLoader
的工作方式,同一 VM 中可能有两个同名的 class,而 StackTraceElement
无法提供足够的信息来区分它们. (这就是像 Tomcat 这样的容器可以为同一 VM 中的两个不同应用程序加载同一库的两个不同版本的方式。)
也许这有助于将来参考,因为我遇到了同样的问题,并且想知道如何做到这一点
您可以使用 StackTraceElement
从 StackTraceElement
获取方法对象:
//replace with your StackTraceElement
StackTraceElement method_obj = Thread.currentThread().getStackTrace()[0]
Class<?> object_context = Class.forName(method_obj.className)
Method method = object_context.getMethod(method_obj.methodName, null)