线程 堆栈跟踪信息 StackTraceElement

本文介绍两种获取Java程序堆栈跟踪信息的方法:一是利用StackTraceElement类遍历当前线程的堆栈信息,二是通过抛出异常并打印堆栈跟踪。同时,文章详细解释了StackTraceElement类的使用及各个方法的意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一:通过 StackTraceElement

方法:
public static void printCallStatck() {
	StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
    //StackTraceElement[] stackElements = new Throwable().getStackTrace();
	if (stackElements != null) {
		for (StackTraceElement stackTraceElement : stackElements) {
			System.out.println("ClassName:" + stackTraceElement.getClassName());
			System.out.println("FileName:" + stackTraceElement.getFileName());
			System.out.println("LineNumber:" + stackTraceElement.getLineNumber());
			System.out.println("MethodName:" + stackTraceElement.getMethodName());
			System.out.println("isNativeMethod:" + stackTraceElement.isNativeMethod());
			System.out.println("信息:" + stackTraceElement.toString());
			System.out.println("-----------------------------------");
		}
	}
}
//StackTraceElement[] stackElements = new Throwable().getStackTrace();
x
1
public static void printCallStatck() {
2
    StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
3
    //StackTraceElement[] stackElements = new Throwable().getStackTrace();
4
    if (stackElements != null) {
5
        for (StackTraceElement stackTraceElement : stackElements) {
6
            System.out.println("ClassName:" + stackTraceElement.getClassName());
7
            System.out.println("FileName:" + stackTraceElement.getFileName());
8
            System.out.println("LineNumber:" + stackTraceElement.getLineNumber());
9
            System.out.println("MethodName:" + stackTraceElement.getMethodName());
10
            System.out.println("isNativeMethod:" + stackTraceElement.isNativeMethod());
11
            System.out.println("信息:" + stackTraceElement.toString());
12
            System.out.println("-----------------------------------");
13
        }
14
    }
15
}
结果:
ClassName:java.lang.Thread
FileName:Thread.java
LineNumber:1552
MethodName:getStackTrace
isNativeMethod:false
信息:java.lang.Thread.getStackTrace(Thread.java:1552)
-----------------------------------
ClassName:Test
FileName:Test.java
LineNumber:7
MethodName:printCallStatck
isNativeMethod:false
信息:Test.printCallStatck(Test.java:7)
-----------------------------------
ClassName:Test
FileName:Test.java
LineNumber:3
MethodName:main
isNativeMethod:false
信息:Test.main(Test.java:3)
-----------------------------------
x
 
1
ClassName:java.lang.Thread
2
FileName:Thread.java
3
LineNumber:1552
4
MethodName:getStackTrace
5
isNativeMethod:false
6
信息:java.lang.Thread.getStackTrace(Thread.java:1552)
7
-----------------------------------
8
ClassName:Test
9
FileName:Test.java
10
LineNumber:7
11
MethodName:printCallStatck
12
isNativeMethod:false
13
信息:Test.printCallStatck(Test.java:7)
14
-----------------------------------
15
ClassName:Test
16
FileName:Test.java
17
LineNumber:3
18
MethodName:main
19
isNativeMethod:false
20
信息:Test.main(Test.java:3)
21
-----------------------------------
注意:
1、数组中元素的个数是不确定个的,这完全取决于打印堆栈信息时经过了几步的调用。
2、并非最后一个元素的就一定是我们最想要的信息,因为在框架中,后续可能还会有很多层的调用,比如在Android中打印日志的一个案例:
dalvik.system.VMStack:getThreadStackTrace:-2
java.lang.Thread:getStackTrace:1566
com.yibasan.lizhifm.ad.Lg:log:58
com.yibasan.lizhifm.ad.Lg:i:34//这里调用了Log.i
com.yibasan.lizhifm.ad.SplashAdManager:canShowAd:66//我们是在这里调用了封装好的Lg类中的Lg.i方法,所以这里的元素是我们最想要的
com.yibasan.lizhifm.activities.BaseActivity:onResume:518
com.yibasan.lizhifm.activities.fm.NavBarActivity:onResume:375
android.app.Instrumentation:callActivityOnResume:1276
android.app.Activity:performResume:6937
android.app.ActivityThread:performResumeActivity:3468
android.app.ActivityThread:handleResumeActivity:3531
android.app.ActivityThread$H:handleMessage:1569
android.os.Handler:dispatchMessage:102
android.os.Looper:loop:154
android.app.ActivityThread:main:6209
java.lang.reflect.Method:invoke:-2
com.android.internal.os.ZygoteInit$MethodAndArgsCaller:run:900
com.android.internal.os.ZygoteInit:main:790
x
 
1
dalvik.system.VMStack:getThreadStackTrace:-2
2
java.lang.Thread:getStackTrace:1566
3
com.yibasan.lizhifm.ad.Lg:log:58
4
com.yibasan.lizhifm.ad.Lg:i:34//这里调用了Log.i
5
com.yibasan.lizhifm.ad.SplashAdManager:canShowAd:66//我们是在这里调用了封装好的Lg类中的Lg.i方法,所以这里的元素是我们最想要的
6
com.yibasan.lizhifm.activities.BaseActivity:onResume:518
7
com.yibasan.lizhifm.activities.fm.NavBarActivity:onResume:375
8
android.app.Instrumentation:callActivityOnResume:1276
9
android.app.Activity:performResume:6937
10
android.app.ActivityThread:performResumeActivity:3468
11
android.app.ActivityThread:handleResumeActivity:3531
12
android.app.ActivityThread$H:handleMessage:1569
13
android.os.Handler:dispatchMessage:102
14
android.os.Looper:loop:154
15
android.app.ActivityThread:main:6209
16
java.lang.reflect.Method:invoke:-2
17
com.android.internal.os.ZygoteInit$MethodAndArgsCaller:run:900
18
com.android.internal.os.ZygoteInit:main:790

方法二:通过 Exception

new Exception("this is a log").printStackTrace();
System.out.println("这里会继续执行");
x
 
1
new Exception("this is a log").printStackTrace();
2
System.out.println("这里会继续执行");
结果
java.lang.Exception: this is a log
	at Test.main(Test.java:3)
这里会继续执行
 
1
java.lang.Exception: this is a log
2
    at Test.main(Test.java:3)
3
这里会继续执行

StackTraceElement 类简介

此类在 java.lang 包下
public final class StackTraceElement extends Object implements Serializable
x
8
 
1
public final class StackTraceElement extends Object implements Serializable
堆栈跟踪元素,它由 Throwable.getStackTrace() 返回。每个元素表示单独的一个【堆栈帧】。所有的堆栈帧(堆栈顶部的那个堆栈帧除外)都表示一个【方法调用】。堆栈顶部的帧表示【生成堆栈跟踪的执行点】。通常,这是创建对应于堆栈跟踪的 throwable 的点。

构造方法

public StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber)
 
1
public StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber)
创建表示指定【执行点】的【堆栈跟踪元素】。
参数:
  • declaringClass - 类的完全限定名,该类包含由堆栈跟踪元素所表示的执行点
  • methodName - 方法名,该方法包含由堆栈跟踪元素所表示的执行点
  • fileName - 文件名,该文件包含由堆栈跟踪元素所表示的执行点;如果该信息不可用,则该参数为 null
  • lineNumber - 源代码行的行号,该代码行包含由堆栈跟踪元素所表示的执行点;如果此信息不可用,则该参数为负数。值 -2 表示包含执行点的方法是一个本机方法
抛出:
  • NullPointerException - 如果 declaringClass 或 methodName 为 null

普通方法

  • String  getClassName()  返回类的完全限定名,该类包含由该堆栈跟踪元素所表示的执行点。
  • String  getFileName()  返回源文件名,该文件包含由该堆栈跟踪元素所表示的执行点。
  • int  getLineNumber()  返回源行的行号,该行包含由该堆栈该跟踪元素所表示的执行点。
  • String  getMethodName()  返回方法名,此方法包含由该堆栈跟踪元素所表示的执行点。
  • boolean  isNativeMethod()  如果包含由该堆栈跟踪元素所表示的执行点的方法是一个本机方法,则返回 true。
重写的Object的方法
  • boolean  equals(Object obj)  如果指定的对象是另一个 StackTraceElement 实例,并且该对象表示的【执行点】与该实例的相同,则返回 ture。
  • int  hashCode()  返回此堆栈跟踪元素的哈希码值。
  • String  toString()  返回表示该堆栈跟踪元素的字符串。
该字符串的格式取决于实现,但是可将以下示例格式视为典型的格式:
"MyClass.mash(MyClass.java:9)" - 其中,"MyClass" 是类的完全限定名,该类包含由该堆栈跟踪元素所表示的执行点;"mash" 是包含执行点的方法的名字;"MyClass.java" 是包含执行点的源文件;"9" 是包含执行点的源行的行号。
"MyClass.mash(MyClass.java)" - 同上,但是行号不可用。
"MyClass.mash(Unknown Source)" - 同上,但是文件名和行号都不可用。
"MyClass.mash(Native Method)" - 同上,但是文件名和行号都不可用,并且已知包含执行点的方法是本机方法。
 
1
该字符串的格式取决于实现,但是可将以下示例格式视为典型的格式:
2
"MyClass.mash(MyClass.java:9)" - 其中,"MyClass" 是类的完全限定名,该类包含由该堆栈跟踪元素所表示的执行点;"mash" 是包含执行点的方法的名字;"MyClass.java" 是包含执行点的源文件;"9" 是包含执行点的源行的行号。
3
"MyClass.mash(MyClass.java)" - 同上,但是行号不可用。
4
"MyClass.mash(Unknown Source)" - 同上,但是文件名和行号都不可用。
5
"MyClass.mash(Native Method)" - 同上,但是文件名和行号都不可用,并且已知包含执行点的方法是本机方法。
2018-1-3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值