J2SE 1.4 Throwable 新增兩構造函數支援異常鏈:
Throwable(Throwable cause)
Throwable(String message, Throwable cause)
舊有異常類可調用 initCause(Throwable) 設置根因。捕獲異常重新拋出時附加原始原因,形成菊花鏈。範例:自定義 TheException 包裝 I/O 異常,捕獲時透過 getCause() 獲取原始原因。
try { fileAccess(); }
catch (Exception e) {
TheException te = new TheException("Prefix too short", e);
throw te;
}
catch (Exception cause) {
System.err.println("Cause: " + cause);
System.err.println("OriginalCause: " + cause.getCause());
}
Throwable.getStackTrace() 返回 StackTraceElement[],可自定義格式輸出。每元素提供:
getClassName()、getFileName()、getLineNumber()、getMethodName()、isNativeMethod()數組[0]為棧頂(拋出點)。範例輸出文件名:行號 => 方法名()。
StackTraceElement[] elements = e.getStackTrace();
for (int i=0; i " + elements[i].getMethodName() + "()");
內建日誌工具替代 System.err。核心:Logger、Level (SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST、ALL、NONE)、Handler (ConsoleHandler、FileHandler 輸出 XML)、LogManager 配置。基本用法:
Logger logger = Logger.getLogger("net.zukowski.ibm");
logger.log(Level.WARNING, "message"); // 或 logger.warning("message")
添加文件處理器:
LogManager manager = LogManager.getLogManager();
Handler handler = new FileHandler("zuk.log");
manager.addGlobalHandler(handler);
文件輸出為 XML 格式,含時間、級別、類、方法、線程、訊息等結構化資訊,利於分析。
<record>
<date>2001-10-30T16:24:23</date>
<level>WARNING</level>
<class>Exceptions</class>
<method>main</method>
<message>arrayAccess</message>
</record>
單一類演示:鏈式異常包裝 I/O 錯誤、ArithmeticException 手動格式化堆棧輸出、ArrayIndexOutOfBoundsException 記錄至 XML 日誌文件。
public class Exceptions {
// ... fileAccess(), divZero(), arrayAccess() 拋出異常 ...
public static void main(String[] args) {
// 鏈式異常
try { try { fileAccess(); } catch (Exception e) { throw new TheException("...", e); } }
catch (Exception c) { System.err.println(c.getCause()); }
// 堆棧手動格式化
try { divZero(); } catch (Exception e) { /* getStackTrace() 迭代輸出 */ }
// 日誌記錄
try { arrayAccess(args); } catch (Exception e) {
LogManager.getLogManager().addGlobalHandler(new FileHandler("zuk.log"));
Logger.getLogger("...").log(Level.WARNING, e.getStackTrace()[0].getMethodName());
}
}
}