Java線程運行軌跡-代碼追蹤與定位

今天在寫程序時,想到一個問題,當我的程序出異常的時候,控制檯輸出信息中,明確指出了出現異常的位置,並詳細列舉了函數的調用層次關係,它是怎麼做到的。

竟然想到了這個問題,就去查看了源代碼,不過沒點幾下,就遇到了native本地方法,只好作罷。於是又去網上找了這方面的資料,最後找到了一點這方面的東西,不過它給出的只是API,卻並沒有對代碼做什麼解釋。代碼如下


public class Test {
	public static int getLineNumber() {
		return Thread.currentThread().getStackTrace()[2].getLineNumber();
	}

	public static String getFileName() {
		return Thread.currentThread().getStackTrace()[2].getFileName();
	}

	public static void main(String args[]) {
		System.out.println("[" + getFileName() + ":" + getLineNumber() + "]" + "Hello World!");
	}
}

這程序中爲什麼要取數組中的第二個呢?原帖沒有給出解釋。

接着,我自己去寫了一段代碼進行測試,代碼如下

class StackTraceDemo
{
	public static void main(String[] args) 
	{
		System.out.println(findLocation(2));
		System.out.println();
		System.out.println(findAllLocation());
	}

	public static String findAllLocation()
	{
		StringBuilder locations = new StringBuilder();
		StackTraceElement elements [] = Thread.currentThread().getStackTrace();

		for(int i=0;i<elements.length;i++){
			locations.append(findLocation(i) +"\n");
		}
	
		return locations.toString();
	}
	
	public static String findLocation(int level)
	{
		StackTraceElement element = Thread.currentThread().getStackTrace()[level];
		return "File: "+element.getFileName()+" Line: "+element.getLineNumber()+" Method: "+element.getMethodName();
	}
}

程序運行得到這樣的結果:

File: StackTraceDemo.java Line: 5 Method: main


File: Thread.java Line: 1567 Method: getStackTrace
File: StackTraceDemo.java Line: 24 Method: findLocation
File: StackTraceDemo.java Line: 16 Method: findAllLocation


從這個結果中來看,之所以前面那個程序選取第二個元素,是因爲Java程序運行時函數入棧是在數組的起始位置入棧,其它的棧元素後移。這是我的個人之見,我也不敢確定自己所想是否正確,歡迎有別的看法的人或知道原理的人留言指點交流。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章