JAVA基础理解-异常处理

异常处理

​​概念理解

什么是异常处理?
程序运行时会出错,而异常可以让程序在出错时,抛出异常提示同时保留错误信息,便于定位错误内容.

编译异常和运行异常的区别?
Checked异常(如IOException):编译器强制要求处理(必须try-catch或throws),否则代码无法编译;
Unchecked异常(如NullPointerException):编译器不强制处理(通常是逻辑错误,如空指针、越界),运行时才可能抛出。

异常处理的两种方式是什么?

  1. throws向上抛出
  2. try...catch​捕获异常并处理​

finally关键字的作用还能和使用场景?
异常无论捕获,都会执行finally下的程序(用于释放资源).

自定义异常的使用场景?​​
当业务逻辑中出现“非JDK内置异常能描述的错误”时(如“用户年龄不能超过150岁”),需自定义异常(继承Exception或RuntimeException)传递明确错误信息。

实践验证

场景1:基础try-catch-finally​
需求:读取文件内容,若文件不存在则提示“文件未找到”,无论是否成功都关闭文件流。

点击查看代码
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ExceptionDemo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File("test.txt"));
            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }
        } catch (IOException e) { // 捕获Checked异常(必须处理)
            System.out.println("文件读取失败:" + e.getMessage());
        } finally {
            if (fis != null) {
                try {
                    fis.close(); // 释放资源(可能抛出IOException,需再次捕获)
                } catch (IOException e) {
                    System.out.println("关闭文件流失败:" + e.getMessage());
                }
            }
        }
    }
}

场景2:throw主动抛异常​​
需求:自定义一个“年龄超过150岁”的异常,当设置年龄时若超过150则抛出。

点击查看代码
class AgeOutOfBoundsException extends RuntimeException { // 自定义Unchecked异常
    public AgeOutOfBoundsException(String message) {
        super(message);
    }
}

public class Person {
    private int age;

    public void setAge(int age) {
        if (age > 150) {
            throw new AgeOutOfBoundsException("年龄不能超过150岁,当前值:" + age); // 主动抛异常
        }
        this.age = age;
    }
}

底层逻辑理解

异常在方法调用栈中会向上传播,直到被捕获或导致程序终止。需能分析以下场景的异常流向:

​​示例代码​​:

点击查看代码
public class ExceptionPropagation {
    public static void main(String[] args) {
        try {
            methodA();
        } catch (IOException e) {
            System.out.println("main捕获到异常:" + e.getMessage());
        }
    }

    public static void methodA() throws IOException { // 声明抛IOException
        methodB();
    }

    public static void methodB() { // 未处理异常
        throw new IOException("原始异常"); // 主动抛异常
    }
}
​​问题​​:异常的传播路径是怎样的?最终谁捕获了异常?

​​正确分析​​:

• methodB抛出IOException → methodA未捕获,将异常向上传播 → main方法中的try-catch捕获该异常 → 程序终止。

​​结构化输出

总结“最佳实践”与“常见错误”

掌握异常处理的关键是理解“何时处理、如何处理、避免哪些坑”

如下:

•对Checked异常:优先在当前方法处理(若能恢复),否则声明throws由上层处理;
•对Unchecked异常:优先修复代码逻辑(如判空避免NPE),而非依赖异常捕获;
•资源释放:用try-with-resources(Java 7+)替代手动finally(更简洁可靠);
•异常信息:记录完整堆栈(如e.printStackTrace()或日志框架),避免丢失调试信息;
•自定义异常:继承RuntimeException(Unchecked)或Exception(Checked),并添加有意义的错误信息。

posted @ 2025-08-18 00:33  张-  阅读(7)  评论(0)    收藏  举报