1. 为什么需要 try-catch?
正如你所知,编程中错误屡见不鲜:除以零、输入不合法、文件缺失,等等。如果不处理这些情况,程序会以错误状态终止(崩溃)。
构造 try-catch 可以“捕获”异常,通过妥善处理错误来防止程序崩溃。
try-catch 构造的语法
try
{
// 可能抛出异常的代码
}
catch (ExceptionType variableName)
{
// 处理异常的代码
}
说明:
- try — “尝试执行这段代码”。
- catch — “如果发生指定类型的异常,在这里处理”。
它是如何工作的?
如果在 try 块中发生异常,该块的执行会立刻中断,控制流转到第一个匹配的 catch 块。若未发生异常——将跳过 catch 块。
2. 示例:除以零
未进行异常处理
int a = 10;
int b = 0;
int result = a / b; // 此处程序将因错误而终止!
System.out.println("结果:" + result); // 不会执行到这里
结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:3)
使用 try-catch 进行处理
int a = 10;
int b = 0;
try
{
int result = a / b; // 此处可能会抛出异常
System.out.println("结果:" + result);
}
catch (ArithmeticException e)
{
System.out.println("错误:不能除以零!");
}
System.out.println("程序已继续运行。");
结果:
错误:不能除以零!
程序已继续运行。
解释:
- 一旦 Java 遇到除以零,就会“抛出”异常。
- try 被中断,控制流转到 catch。
- 错误处理完成后,程序继续执行。
3. catch 块如何工作
在 catch 后面的括号中,需指定异常的类型(例如,ArithmeticException)以及变量名(通常为 e)。
在 catch 块内部可以获取错误的详细信息:
- e.getMessage() —— 错误的简要描述。
- e.printStackTrace() —— 详细信息(用于调试)。
示例:
try
{
int[] arr = new int[2];
int x = arr[10]; // 错误:索引不存在
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("错误:" + e.getMessage()); // 输出错误信息
e.printStackTrace(); // 在控制台打印错误的全部信息
}
4. 发生异常时的执行流程
如果在 try 块中没有错误——将跳过 catch 块。
如果在 try 块中出现错误——执行会在出错位置中断,控制流立刻转到第一个匹配的 catch。在 try 中出错之后的代码将不会再执行!
示意:
try
{
System.out.println("1. try 开始");
int a = 10 / 0; // 错误!
System.out.println("2. 除法之后"); // 不会执行
}
catch (ArithmeticException e)
{
System.out.println("3. 在 catch 块中");
}
System.out.println("4. try-catch 之后");
结果:
1. try 开始
3. 在 catch 块中
4. try-catch 之后
5. 使用 try-catch 时的常见错误
错误 № 1:过于宽泛的 catch。
如果使用 catch (Exception e),你可能会捕获大量意料之外且无法正确处理的错误。
解决方案:只捕获在该位置确实预期会出现的异常(例如,IOException、SQLException)。
错误 № 2:空的 catch。
写成 catch (Exception e) {} 等于把问题掩盖起来。程序可能在其他地方崩溃,或者表现异常。
解决方案:至少要记录错误(e.printStackTrace() 或使用日志记录器)。
错误 № 3:相信 try-catch 能修复一切问题。
如果错误在于程序逻辑(例如除以零、算法错误)——再多的 try-catch 也无济于事。
解决方案:仅在确实可预期的情形下使用 try-catch,不要用它来掩盖缺陷。
GO TO FULL VERSION