catch 关键字
概述
catch
关键字用于捕获和处理try块中抛出的异常,必须与try块一起使用。
语法格式
try {
// 可能抛出异常的代码
} catch (ExceptionType e) {
// 异常处理代码
} catch (AnotherExceptionType e) {
// 处理另一种异常
}
基本用法
public class CatchExample {
public static void main(String[] args) {
// 捕获算术异常
try {
int result = 10 / 0;
System.out.println("结果: " + result);
} catch (ArithmeticException e) {
System.out.println("除零错误: " + e.getMessage());
}
// 捕获数组越界异常
try {
int[] array = {1, 2, 3};
System.out.println(array[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界: " + e.getMessage());
}
System.out.println("程序继续执行");
}
}
多个catch块
import java.io.*;
public class MultipleCatchExample {
public static void readFile(String filename) {
try {
FileInputStream file = new FileInputStream(filename);
byte[] data = new byte[100];
file.read(data);
file.close();
// 可能的字符串转换
String content = new String(data);
int number = Integer.parseInt(content.trim());
System.out.println("读取的数字: " + number);
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO错误: " + e.getMessage());
} catch (NumberFormatException e) {
System.out.println("数字格式错误: " + e.getMessage());
} catch (Exception e) {
System.out.println("其他错误: " + e.getMessage());
}
}
public static void main(String[] args) {
readFile("nonexistent.txt");
readFile("data.txt");
}
}
多重异常捕获(Java 7+)
public class MultiCatchExample {
public static void processData(String data) {
try {
// 可能抛出多种异常的操作
int length = data.length();
int number = Integer.parseInt(data);
int result = 100 / number;
System.out.println("处理结果: " + result);
} catch (NullPointerException | NumberFormatException e) {
System.out.println("数据格式错误: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("算术错误: " + e.getMessage());
}
}
public static void main(String[] args) {
processData(null); // NullPointerException
processData("abc"); // NumberFormatException
processData("0"); // ArithmeticException
processData("5"); // 正常执行
}
}
异常信息获取
public class ExceptionInfoExample {
public static void demonstrateExceptionInfo() {
try {
String str = null;
int length = str.length();
} catch (NullPointerException e) {
System.out.println("异常类型: " + e.getClass().getSimpleName());
System.out.println("异常消息: " + e.getMessage());
System.out.println("异常字符串: " + e.toString());
System.out.println("\n堆栈跟踪:");
e.printStackTrace();
System.out.println("\n堆栈跟踪元素:");
StackTraceElement[] stack = e.getStackTrace();
for (StackTraceElement element : stack) {
System.out.println(" " + element.toString());
}
}
}
public static void main(String[] args) {
demonstrateExceptionInfo();
}
}
异常重新抛出
public class RethrowExample {
public static void processOrder(String orderId) throws Exception {
try {
if (orderId == null || orderId.isEmpty()) {
throw new IllegalArgumentException("订单ID不能为空");
}
// 模拟数据库操作
if (orderId.equals("INVALID")) {
throw new RuntimeException("数据库连接失败");
}
System.out.println("处理订单: " + orderId);
} catch (IllegalArgumentException e) {
System.out.println("参数错误,记录日志");
throw e; // 重新抛出异常
} catch (RuntimeException e) {
System.out.println("运行时错误,记录错误日志");
// 包装异常后重新抛出
throw new Exception("订单处理失败: " + e.getMessage(), e);
}
}
public static void main(String[] args) {
try {
processOrder("");
} catch (Exception e) {
System.out.println("最终捕获: " + e.getMessage());
}
try {
processOrder("INVALID");
} catch (Exception e) {
System.out.println("最终捕获: " + e.getMessage());
System.out.println("原因: " + e.getCause().getMessage());
}
}
}
资源管理中的catch
import java.io.*;
public class ResourceManagementExample {
// 传统方式 - 需要手动关闭资源
public static void readFileTraditional(String filename) {
FileInputStream fis = null;
try {
fis = new FileInputStream(filename);
// 读取文件操作
byte[] buffer = new byte[1024];
int bytesRead = fis.read(buffer);
System.out.println("读取了 " + bytesRead + " 字节");
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
System.out.println("读取错误: " + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.out.println("关闭文件失败: " + e.getMessage());
}
}
}
}
// try-with-resources方式(推荐)
public static void readFileWithResources(String filename) {
try (FileInputStream fis = new FileInputStream(filename)) {
byte[] buffer = new byte[1024];
int bytesRead = fis.read(buffer);
System.out.println("读取了 " + bytesRead + " 字节");
} catch (FileNotFoundException e) {
System.out.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
System.out.println("读取错误: " + e.getMessage());
}
// 资源自动关闭
}
public static void main(String[] args) {
readFileTraditional("test.txt");
readFileWithResources("test.txt");
}
}
最佳实践
public class CatchBestPractices {
// 好的做法:具体异常处理
public static void goodPractice() {
try {
// 业务逻辑
performOperation();
} catch (SpecificException e) {
// 针对性处理
handleSpecificException(e);
} catch (AnotherException e) {
// 另一种处理
handleAnotherException(e);
} catch (Exception e) {
// 通用处理(最后的保障)
handleGenericException(e);
}
}
// 避免的做法:忽略异常
public static void badPractice() {
try {
performOperation();
} catch (Exception e) {
// 什么都不做 - 这是不好的做法
}
}
private static void performOperation() throws Exception {
throw new Exception("示例异常");
}
private static void handleSpecificException(Exception e) {
System.out.println("处理特定异常: " + e.getMessage());
}
private static void handleAnotherException(Exception e) {
System.out.println("处理另一种异常: " + e.getMessage());
}
private static void handleGenericException(Exception e) {
System.out.println("通用异常处理: " + e.getMessage());
e.printStackTrace();
}
}
catch关键字是Java异常处理机制的核心,正确使用它可以让程序更加健壮和用户友好。