JAVA基础理解-异常处理
异常处理
概念理解
什么是异常处理?
程序运行时会出错,而异常可以让程序在出错时,抛出异常提示同时保留错误信息,便于定位错误内容.
编译异常和运行异常的区别?
Checked异常(如IOException):编译器强制要求处理(必须try-catch或throws),否则代码无法编译;
Unchecked异常(如NullPointerException):编译器不强制处理(通常是逻辑错误,如空指针、越界),运行时才可能抛出。
异常处理的两种方式是什么?
- throws向上抛出
- 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),并添加有意义的错误信息。