今天在寫程式時,想到一個問題,當我的程式出異常的時候,控制台輸出資訊中,明确指出了出現異常的位置,并詳細列舉了函數的調用層次關系,它是怎麼做到的。
竟然想到了這個問題,就去檢視了源代碼,不過沒點幾下,就遇到了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程式運作時函數入棧是在數組的起始位置入棧,其它的棧元素後移。這是我的個人之見,我也不敢确定自己所想是否正确,歡迎有别的看法的人或知道原理的人留言指點交流。