StackTraceElement獲取方法調(diào)用棧信息實例詳解
本文研究的主要是StackTraceElement獲取方法調(diào)用棧信息的相關(guān)內(nèi)容,具體介紹和實例如下。
一、什么是StackTrace
StackTrace(堆棧軌跡)存放的就是方法調(diào)用棧的信息,異常處理中常用的printStackTrace()實質(zhì)就是打印異常調(diào)用的堆棧信息。
二、StackTraceElement介紹
StackTraceElement表示StackTrace(堆棧軌跡)中的一個方法對象,屬性包括方法的類名、方法名、文件名以及調(diào)用的行數(shù)。
public final class StackTraceElement implements java.io.Serializable {
// Normally initialized by VM (public constructor added in 1.5)
private String declaringClass;
private String methodName;
private String fileName;
private int lineNumber;
}
StackTraceElement被定義為final,可見其作為一個java的基礎(chǔ)類不允許被繼承。
獲取StackTraceElement的方法有兩種,均返回StackTraceElement數(shù)組,也就是這個棧的信息。
1、Thread.currentThread().getStackTrace()
2、new Throwable().getStackTrace()
StackTraceElement數(shù)組包含了StackTrace(堆棧軌跡)的內(nèi)容,通過遍歷它可以得到方法間的調(diào)用過程,即可以得到當前方法以及其調(diào)用者的方法名、調(diào)用行數(shù)等信息
public class TestClass {
public static void main(String[] args)
{
new TestClass().methodA();
}
private void methodA(){
System.out.println("------進入methodA----------");
methodB();
}
private void methodB(){
System.out.println("------進入methodB----------");
StackTraceElement elements[] = Thread.currentThread().getStackTrace();
for (int i = 0; i < elements.length; i++) {
StackTraceElement stackTraceElement=elements[i];
String className=stackTraceElement.getClassName();
String methodName=stackTraceElement.getMethodName();
String fileName=stackTraceElement.getFileName();
int lineNumber=stackTraceElement.getLineNumber();
System.out.println("StackTraceElement數(shù)組下標 i="+i+",fileName="
+fileName+",className="+className+",methodName="+methodName+",lineNumber="+lineNumber);
}
}
}
三、用途
1、我們可以封裝一個日志庫,在打印目標日志的時候,也可以通過這個調(diào)用棧打印出這個日志所在的行數(shù),這樣就可以迅速的定位到日志輸出行,再也不要全局搜索去查找了。
public static void d(String tag, String msg, Object... params) {
StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
Log.d(tag, "(" + targetStackTraceElement.getFileName() + ":"
+ targetStackTraceElement.getLineNumber() + ")");
Log.d(tag, String.format(msg, params));
}
2、如果我們寫了一個SDK,希望某個方法在固定的位置被調(diào)用,我們也可以在這個方法被調(diào)用的時候,進行檢查,看這個方法的調(diào)用位置是否正確。
例如,必須在Activity.onResume中執(zhí)行,PVSdk.onResume,所以我們在調(diào)用PVSdk.onResume方法的時候,在PVSdk.onResume方法里面來通過獲取調(diào)用棧的信息檢測這個方法是否在Activity的onResume方法中調(diào)用的。
public class PVSdk {
public static void onResume() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
Boolean result = false;
for (StackTraceElement stackTraceElement : stackTrace) {
String methodName = stackTraceElement.getMethodName();
String className = stackTraceElement.getClassName();
try {
Boolean assignableFromClass = Class.forName(className).isAssignableFrom(Activity.class);
if (assignableFromClass && "onResume".equals(methodName)) {
result = true;
break;
}
}
catch (ClassNotFoundException e) {
}
}
if (!result)
throw new RuntimeException("PVSdk.onResume must in Activity.onResume");
}
}
3、我們在進行源碼分析的時候,如果想分析整個代碼的執(zhí)行流程,我們可以進行通過打印棧的信息來獲取,這個在源碼分析的時候還是挺有用的。
總結(jié)
以上就是本文關(guān)于StackTraceElement獲取方法調(diào)用棧信息實例詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
相關(guān)文章
mybatis返回map結(jié)果集@MapKey使用的場景分析
這篇文章主要介紹了mybatis返回map結(jié)果集@MapKey使用的場景分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
Java 將List中的實體類按照某個字段進行分組并存放至Map中操作
這篇文章主要介紹了Java 將List中的實體類按照某個字段進行分組并存放至Map中操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Java跨session實現(xiàn)token接口測試過程圖解
這篇文章主要介紹了Java跨session實現(xiàn)token接口測試過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04

