Java案例如何捕获异常?

wen java案例 10

本文目录导读:

Java案例如何捕获异常?

  1. 基础 try-catch 结构
  2. 多个 catch
  3. try-catch-finally 结构
  4. try-with-resources(JDK 7+)
  5. 嵌套 try-catch
  6. 自定义异常类
  7. 常见异常处理模式
  8. 最佳实践示例
  9. 关键要点

在Java中捕获异常主要通过 try-catch-finallytry-with-resources 结构来实现,以下是详细的案例和说明:

基础 try-catch 结构

public class ExceptionDemo1 {
    public static void main(String[] args) {
        try {
            // 可能抛出异常的代码
            int result = 10 / 0;  // 算术异常
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("捕获到算术异常: " + e.getMessage());
            e.printStackTrace();  // 打印异常堆栈
        }
        System.out.println("程序继续执行...");
    }
}

多个 catch

public class ExceptionDemo2 {
    public static void main(String[] args) {
        try {
            String str = null;
            System.out.println(str.length());  // NullPointerException
            int[] arr = new int[5];
            arr[10] = 100;  // ArrayIndexOutOfBoundsException
        } catch (NullPointerException e) {
            System.out.println("空指针异常: " + e);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常: " + e);
        } catch (Exception e) {
            // 捕获所有其他异常(放在最后)
            System.out.println("其他异常: " + e);
        }
    }
}

try-catch-finally 结构

public class ExceptionDemo3 {
    public static void main(String[] args) {
        java.io.FileReader reader = null;
        try {
            reader = new java.io.FileReader("test.txt");
            // 读取文件操作
        } catch (java.io.FileNotFoundException e) {
            System.out.println("文件未找到: " + e);
        } finally {
            // 无论是否发生异常,都会执行
            System.out.println("finally 块总是执行");
            try {
                if (reader != null) {
                    reader.close();  // 关闭资源
                }
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }
    }
}

try-with-resources(JDK 7+)

import java.io.*;
public class ExceptionDemo4 {
    public static void main(String[] args) {
        // 自动关闭资源(资源必须实现 AutoCloseable 接口)
        try (FileReader reader = new FileReader("test.txt");
             BufferedReader br = new BufferedReader(reader)) {
            String line = br.readLine();
            System.out.println("读取内容: " + line);
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e);
        } catch (IOException e) {
            System.out.println("IO异常: " + e);
        }
        // 无需 finally 手动关闭资源
    }
}

嵌套 try-catch

public class ExceptionDemo5 {
    public static void main(String[] args) {
        try {
            try {
                // 内部 try 块
                int[] arr = new int[5];
                arr[10] = 100;
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("内部异常捕获: " + e);
                // 可以重新抛出异常到外部
                throw new RuntimeException("重新抛出的异常", e);
            }
        } catch (RuntimeException e) {
            System.out.println("外部异常捕获: " + e);
            System.out.println("原始原因: " + e.getCause());
        }
    }
}

自定义异常类

// 自定义异常
class InsufficientBalanceException extends Exception {
    public InsufficientBalanceException(String message) {
        super(message);
    }
}
class BankAccount {
    private double balance = 100.0;
    public void withdraw(double amount) throws InsufficientBalanceException {
        if (amount > balance) {
            throw new InsufficientBalanceException("余额不足!当前余额: " + balance);
        }
        balance -= amount;
        System.out.println("取款成功,剩余余额: " + balance);
    }
}
public class ExceptionDemo6 {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        try {
            account.withdraw(200.0);
        } catch (InsufficientBalanceException e) {
            System.out.println("捕获自定义异常: " + e.getMessage());
        }
    }
}

常见异常处理模式

public class ExceptionDemo7 {
    // 1. 记录日志
    private static final java.util.logging.Logger logger = 
        java.util.logging.Logger.getLogger(ExceptionDemo7.class.getName());
    public static void main(String[] args) {
        // 2. 抛出异常(不处理,交由上层调用者处理)
        try {
            validateAge(-5);
        } catch (IllegalArgumentException e) {
            System.out.println("捕获验证异常: " + e.getMessage());
        }
        // 3. 转换异常类型
        try {
            convertException();
        } catch (MyBusinessException e) {
            System.out.println("业务异常: " + e.getMessage());
            if (e.getCause() != null) {
                System.out.println("原始原因: " + e.getCause());
            }
        }
    }
    public static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数: " + age);
        }
    }
    public static void convertException() throws MyBusinessException {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            // 将异常转换为业务异常
            throw new MyBusinessException("运算错误", e);
        }
    }
}
// 自定义业务异常
class MyBusinessException extends Exception {
    public MyBusinessException(String message) {
        super(message);
    }
    public MyBusinessException(String message, Throwable cause) {
        super(message, cause);
    }
}

最佳实践示例

public class ExceptionBestPractice {
    public static void main(String[] args) {
        processFile("data.txt");
    }
    public static void processFile(String filename) {
        // 使用 try-with-resources 自动管理资源
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                processLine(line);
            }
        } catch (FileNotFoundException e) {
            // 明确告诉用户文件不存在
            System.err.println("错误: 文件 '" + filename + "' 未找到");
            System.err.println("请检查文件路径是否正确");
        } catch (IOException e) {
            // 记录日志并给出友好提示
            System.err.println("读取文件时发生错误: " + e.getMessage());
            // 在正式应用中应记录日志
            e.printStackTrace();
        } catch (Exception e) {
            // 捕获所有未预期的异常
            System.err.println("处理文件时发生未知错误");
            e.printStackTrace();
        }
    }
    private static void processLine(String line) {
        if (line == null || line.isEmpty()) {
            throw new IllegalArgumentException("行内容不能为空");
        }
        System.out.println("处理: " + line);
    }
}

关键要点

  1. 捕获特定异常优于通用异常 - 先捕获具体异常,最后才是 Exception
  2. 使用 finally 块释放资源 - 或使用 try-with-resources
  3. 避免空的 catch - 至少要记录异常
  4. 异常类型选择
    • 可恢复异常:使用受检异常
    • 编程错误:使用运行时异常
  5. 异常信息要具体 - 提供有意义的异常消息
  6. 保持异常链完整 - 使用 initCause() 或构造函数传递原因异常

这些示例涵盖了Java异常处理的主要方式,根据具体场景选择合适的方式来捕获和处理异常。

抱歉,评论功能暂时关闭!