如何在Java程序出現異常時輸出其文件和行號?
使用了如下方法獲得異常所在的文件,行號和方法:
StackTraceElement stackTraceElement= ex.getStackTrace()[0];// 得到異常棧的首個元素
System.out.println("File="+stackTraceElement.getFileName());// 打印文件名
System.out.println("Line="+stackTraceElement.getLineNumber());// 打印出錯行號
System.out.println("Method="+stackTraceElement.getMethodName());// 打印出錯方法
程序如下:
public class ExceptionTest{
public static void main(String[] arg) {
try{
throw new Exception("Exception Test!");
}
catch(Exception ex){
ex.printStackTrace();
String strTemp=ex.getStackTrace().toString();
StackTraceElement stackTraceElement= ex.getStackTrace()[0];
System.out.println("File="+stackTraceElement.getFileName());
System.out.println("Line="+stackTraceElement.getLineNumber());
System.out.println("Method="+stackTraceElement.getMethodName());
}
}
}
輸出如下(在Eclipse3.1中):
java.lang.Exception: Exception Test!
at ExceptionTest.main(ExceptionTest.java:5)
File=ExceptionTest.java
Line=5
Method=main
大家可以看到,輸出基本可以滿足需求,但是沒有ex.printStackTrace();產生的鏈接效果,如點擊ExceptionTest.java:5 就可以到達錯誤處,這里不知道如何處理,那位知道請告知.
然而,上述方法不能應付類反射出現的異常,請大家看如下程序:
public void fetchCommand(String strCmmd){
cmmdArgs=strCmmd.split("/s+");
String className="Command"+cmmdArgs[0];
try{
Class cls=Class.forName(className);
cmmd=(Command)cls.newInstance();
}
catch(Exception ex){
ex.printStackTrace();
//System.out.println(ex.getStackTrace()[0].getLineNumber());///getFileName() ;
StackTraceElement stackTraceElement= ex.getStackTrace()[0];
System.out.println("File="+stackTraceElement.getFileName());
System.out.println("Line="+stackTraceElement.getLineNumber());
System.out.println("Method="+stackTraceElement.getMethodName());
}
}
當className不是可識別的類名時,輸出如下:
commandType01 start!
commandType01 Length=3
commandType01 End!
commandType02 start!
commandType02 is: Type02 1 2 3 4
commandType02 End!
File=null // 這里找不到文件
Line=-1 // 行出錯
Method=run // 方法錯
commandType02 start!
commandType02 is: Type04 USA Russia China
commandType02 End!
java.lang.ClassNotFoundException: CommandType04
at java.net.URLClassLoader.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at Mediation.fetchCommand(Mediation.java:16) // 這里倒是對了
at Inlet.main(Inlet.java:11)// 這里也對
看來StackTraceElement stackTraceElement= ex.getStackTrace()[0];還要繼續挖掘.
經跟蹤發現,現在用這個辦法可以完全搞定:
StackTraceElement stackTraceElement= ex.getStackTrace()[ex.getStackTrace().length-1];
System.out.println("File="+stackTraceElement.getFileName());
System.out.println("Line="+stackTraceElement.getLineNumber());
System.out.println("Method="+stackTraceElement.getMethodName());
這里的變化是將ex.getStackTrace()[0]修改成了ex.getStackTrace()[ex.getStackTrace().length-1],因為只有數組的最后一個元素才有我想要的信息,原先的ex.getStackTrace()[0]只是恰巧數組的最后一個元素就是首個元素而已.