Java Throwable 类
最后修改时间:2025 年 4 月 13 日
java.lang.Throwable
类是 Java 中所有错误和异常的超类。它是 Java 异常处理机制的基础。理解 Throwable 对于正确的错误处理至关重要。
Throwable 包含创建时执行堆栈的快照。它提供了访问此堆栈跟踪和获取错误原因的方法。所有异常和错误都继承自 Throwable,使其成为 Java 错误层次结构的根。
Throwable 类方法
Throwable 类提供了几种用于错误处理和调试的方法。主要方法包括 getMessage
、getCause
、printStackTrace
和 getStackTrace
。这些方法有助于有效地诊断和处理错误。
public class Throwable implements Serializable { public Throwable() {...} public Throwable(String message) {...} public Throwable(String message, Throwable cause) {...} public Throwable(Throwable cause) {...} public String getMessage() {...} public String getLocalizedMessage() {...} public Throwable getCause() {...} public void printStackTrace() {...} public StackTraceElement[] getStackTrace() {...} public void setStackTrace(StackTraceElement[] stackTrace) {...} public final void addSuppressed(Throwable exception) {...} public final Throwable[] getSuppressed() {...} }
上面的代码显示了 Throwable 类提供的主要方法。这些方法允许检查错误详细信息、原因以及发生错误时的执行堆栈跟踪。
基本异常处理
此示例演示了使用 try-catch 块的基本异常处理。我们捕获除以零时发生的 ArithmeticException。 catch 块打印异常消息和堆栈跟踪。
package com.zetcode; public class Main { public static void main(String[] args) { try { int result = divide(10, 0); System.out.println("Result: " + result); } catch (ArithmeticException e) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); } } public static int divide(int a, int b) { return a / b; } }
执行时,此代码会捕获除以零引发的 ArithmeticException。 catch 块打印错误消息和完整的堆栈跟踪,显示异常发生的位置。 这有助于调试问题。
自定义异常类
此示例显示了如何通过扩展 Exception 来创建自定义异常。我们定义了一个 InsufficientFundsException,其中包括当前余额和请求的金额。这提供了有关错误的更多上下文。
package com.zetcode; class InsufficientFundsException extends Exception { private double balance; private double amount; public InsufficientFundsException(double balance, double amount) { super("Insufficient funds: balance=" + balance + ", amount=" + amount); this.balance = balance; this.amount = amount; } public double getBalance() { return balance; } public double getAmount() { return amount; } } class Account { private double balance; public Account(double balance) { this.balance = balance; } public void withdraw(double amount) throws InsufficientFundsException { if (amount > balance) { throw new InsufficientFundsException(balance, amount); } balance -= amount; } } public class Main { public static void main(String[] args) { Account account = new Account(100); try { account.withdraw(150); } catch (InsufficientFundsException e) { System.err.println(e.getMessage()); System.err.println("Short by: " + (e.getAmount() - e.getBalance())); } } }
自定义异常提供了有关错误条件的详细信息。 捕获后,我们可以访问标准消息和附加字段。 这使得错误处理更具信息性和精确性。
链式异常
Java 允许链接异常,以便在包装异常时保留原始原因。此示例演示了如何使用接受原因的 Throwable 构造函数来创建和处理链式异常。
package com.zetcode; import java.io.IOException; public class Main { public static void main(String[] args) { try { processFile("nonexistent.txt"); } catch (ApplicationException e) { System.err.println("Caught: " + e.getMessage()); System.err.println("Original cause: " + e.getCause().getMessage()); e.getCause().printStackTrace(); } } public static void processFile(String filename) throws ApplicationException { try { // Simulate file operation that fails throw new IOException("File not found: " + filename); } catch (IOException e) { throw new ApplicationException("Failed to process file", e); } } } class ApplicationException extends Exception { public ApplicationException(String message, Throwable cause) { super(message, cause); } }
此示例显示了一个常见的模式,其中低级别的 IOException 被包装在高级别的 ApplicationException 中。 保留了原始原因,以后可以访问。 这在提供特定于应用程序的语义的同时,保持了完整的错误上下文。
打印堆栈跟踪
Throwable 类提供了几种打印堆栈跟踪的方法。 此示例演示了访问和打印堆栈跟踪信息的不同方法,包括标准 printStackTrace 和 getStackTrace 方法。
package com.zetcode; public class Main { public static void main(String[] args) { try { method1(); } catch (Exception e) { // Standard stack trace to stderr e.printStackTrace(); // Print stack trace to System.out e.printStackTrace(System.out); // Access stack trace elements programmatically System.out.println("\nStack trace elements:"); for (StackTraceElement element : e.getStackTrace()) { System.out.println(element); } } } public static void method1() { method2(); } public static void method2() { method3(); } public static void method3() { throw new RuntimeException("Test exception"); } }
此代码演示了访问堆栈跟踪信息的三种方法。 标准 printStackTrace 输出到 stderr,而重载版本可以重定向输出。 getStackTrace 方法允许以编程方式访问每个堆栈帧。
抑制异常
Java 7 引入了抑制异常来处理发生多个异常的情况,例如在 try-with-resources 块中。此示例显示了如何使用 getSuppressed 访问抑制的异常。
package com.zetcode; class Resource implements AutoCloseable { private String name; public Resource(String name) { this.name = name; } public void use() throws Exception { throw new Exception("Error using resource " + name); } @Override public void close() throws Exception { throw new Exception("Error closing resource " + name); } } public class Main { public static void main(String[] args) { try (Resource res1 = new Resource("1"); Resource res2 = new Resource("2")) { res1.use(); res2.use(); } catch (Exception e) { System.out.println("Caught: " + e.getMessage()); System.out.println("Suppressed exceptions:"); for (Throwable t : e.getSuppressed()) { System.out.println(" - " + t.getMessage()); } } } }
在此 try-with-resources 示例中,use() 和 close() 方法都会抛出异常。 主要异常是来自 use() 的异常,而 close() 异常被添加为抑制的异常。 这会将所有错误信息保存在单个异常对象中。
错误 vs 异常
此示例演示了 Errors 和 Exceptions 之间的区别,它们都扩展了 Throwable。 Errors 通常表示应用程序不应尝试捕获的严重问题,而 Exceptions 表示可能被处理的条件。
package com.zetcode; public class Main { public static void main(String[] args) { // Handling a checked exception try { throw new Exception("This is a regular exception"); } catch (Exception e) { System.out.println("Caught Exception: " + e.getMessage()); } // Attempting to handle an Error (not recommended) try { throw new OutOfMemoryError("This is an error"); } catch (Error e) { System.out.println("Caught Error: " + e.getMessage()); } // Uncaught Error will terminate the program throw new StackOverflowError("This will terminate the program"); } }
该示例表明,虽然 Errors 和 Exceptions 都可以被捕获,但 Errors 通常表示无法恢复的条件。 该程序尝试处理 OutOfMemoryError(在实践中不推荐),最后抛出一个未捕获的 StackOverflowError,从而终止执行。
来源
本教程介绍了 Throwable 类,它是 Java 错误处理的基础。 我们探讨了异常处理、自定义异常、链接、堆栈跟踪、抑制异常以及 Error/Exception 的区别。
作者
列出所有Java教程。