异常

1.知识

1. Java 异常体系是怎样的?

  • 所有的异常都继承自 Throwable
    • Error:JVM 错误(如 OutOfMemoryErrorStackOverflowError),程序一般不处理
    • Exception:程序可处理的异常
      • 受检异常(Checked Exception)
        • 编译器强制要求处理
        • IOExceptionSQLException
      • 非受检异常(Unchecked Exception)
        • 运行时异常,继承自 RuntimeException
        • NullPointerExceptionArrayIndexOutOfBoundsException

💡 面试加分:能口头画出继承树(Throwable → Error / Exception → RuntimeException)


2. 受检异常和非受检异常?区别?

维度 受检异常(Checked) 非受检异常(Unchecked)
检查时机 编译时检查 编译时不检查
是否必须处理 必须用 try-catch 捕获 或 throws 声明 不强制,可不处理
典型场景 外部环境问题(文件不存在、网络断开、数据库连接失败) 程序逻辑错误(空指针、数组越界、非法参数)
父类 Exception(但不是 RuntimeException RuntimeException

⚠️ 常见误区:认为“运行时异常不能处理”——其实可以捕获,只是编译器不强制。


3. throwthrows 有什么区别?

关键字 作用 位置 示例
throw 抛出一个具体的异常对象 方法体内 throw new IllegalArgumentException("无效参数");
throws 声明方法可能抛出的异常类型 方法签名后 public void readFile() throws IOException

✅ 记忆口诀:
throw = 动作(扔一个球)throws = 声明(我可能会扔)


4. finally 一定执行吗?

绝大多数情况下会执行,但有极少数例外

  • 程序提前终止:比如调用了 System.exit(0)
  • JVM 崩溃(如死机、断电)
  • trycatch 中写了无限循环死锁,导致无法走到 finally

✅ 正常情况(包括 returnthrow)下,finally 都会执行!

⚠️ 经典陷阱:

public int getValue() {
    try {
        return 1;
    } finally {
        System.out.println("一定会打印");
    }
}

💡 面试加分:知道 try-with-resources 是 finally 的现代替代方案(自动关闭资源)

二、中小厂可能手撕的代码题

题1:写出一个带异常处理的文件读取方法

public String readFile(String path) {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    } catch (IOException e) {
        // ❌ 避免吃掉异常!至少打印或记录
        System.err.println("文件读取失败: " + path + ", 原因: " + e.getMessage());
        return null; // 或抛出自定义异常(更推荐)
    }
}

✅ 加分写法:抛出自定义业务异常,而不是返回 null

题2:自定义异常(加分项!)

// 自定义业务异常(通常继承 RuntimeException)
class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

// 使用
if (age < 0 || age > 150) {
    throw new InvalidAgeException("年龄不合法: " + age);
}

💡 建议:自定义异常名以 Exception 结尾,语义清晰(如 UserNotFoundException)

📌 面试高频追问(准备一下!)

Q:为什么 RuntimeException 不需要声明?
A:因为它是程序 bug,应该在开发阶段修复,而不是靠异常处理掩盖。
Q:catch 里什么都不写(空块)有什么问题?
A:异常被静默吞掉,程序状态不可知,极难排查问题!应至少记录日志。
Q:多个 catch 块怎么排序?
A:子类异常在前,父类在后(否则编译报错)。


新手复习总结,可能有错,若有出入的地方麻烦大佬修正🙏

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐