【8 期】面试官:Java 的异常体系

异常是程序在运行过程中遇到的非正常情况。

在 Java 中,所有的异常类都是 java.lang.Throwable 的子类,主要分为两大类:Exception(异常)和 Error(错误)。

Exception

Exception 是程序在运行时遇到的预期之外但正常情况下可以预见并且应该被捕获和处理的情况

Exception 分为两大类:Checked Exception(可检查异常或编译时异常)和 Unchecked Exception(不可检查异常或运行时异常)。

Checked Exception:在编译阶段就需要处理的异常,进行捕获或声明抛出如通过 try-catch 或 throws 语句;这些异常有 IOException、SQLException 等。

Unchecked Exception:在运行时抛出且编译器不强制处理,比如 NullPointerException、ArrayIndexOutOfBoundsException 等,但仍建议我们通过良好的编程习惯来预防和处理。

Error

Error 表示系统级错误或者严重的资源故障,这些错误通常无法预见,也不需要由程序来恢复或处理。

它们通常是 JVM 内部错误或者是系统的严重故障,由 JVM 抛出。如内存溢出(OutOfMemoryError)、虚拟机错误(VirtualMachineError)、类定义错误(NoClassDefFoundError)等。

对于大多数 Error 类型,由于其严重性和底层性,应用程序往往难以进行有效捕获和恢复,因为它们通常意味着 Java 虚拟机已无法维持正常执行状态。

以下是一些常见的 Checked Exception 示例:

  1. IOException:当发生与输入/输出操作相关的错误时抛出,如文件读写失败、网络通信中断等。
  2. SQLException:在执行数据库操作期间遇到问题时抛出。
  3. ClassNotFoundException:在试图动态加载类但找不到指定类时抛出。
  4. FileNotFoundException:尝试打开不存在的文件时抛出。
  5. MalformedURLException:在构造 URL 对象时,如果 URL 格式不正确会抛出此异常。
  6. ServletException:在处理 Servlet 请求时发生的可预知错误。
  7. ParseException:在解析数据(例如日期、XML、JSON 等)时出现格式错误或其他问题。

以下是一些常见的 Unchecked Exception 示例:

  1. NullPointerException:当试图访问一个为 null 的对象的实例方法或属性时抛出。
  2. ArrayIndexOutOfBoundsException:数组索引超出其有效范围时抛出。
  3. IllegalArgumentException:向方法传递非法或不合适的参数时抛出。
  4. IllegalStateException:当对象处于无法执行请求的状态时抛出。
  5. NumberFormatException:当试图将字符串转换为数值类型但格式不正确时抛出。
  6. ArithmeticException:在进行算术运算时遇到违反基本数学规则的情况,例如除数为零。
  7. ConcurrentModificationException:并发修改集合而未通过迭代器安全地操作时抛出。

异常处理机制

在 Java 中,我们使用 try-catch-finally 语语句块来捕获和处理异常。当 try 块中的代码发生异常时,会立即跳转到匹配的 catch 块进行异常处理,finally 块中的代码无论是否发生异常都会被执行,用于资源清理等操作。

另外,还可以通过在方法签名上声明 throws 关键字将异常传递给调用者处理。

请写出一段代码,展示如何捕获并重新抛出异常。

try {
    // 假设这里有一个可能会抛出IOException的操作
    FileInputStream fis = new FileInputStream("non_existent_file.txt");
} catch (FileNotFoundException e) {
    // 捕获到FileNotFoundException后,重新封装并抛出一个新的RuntimeException
    throw new RuntimeException("File not found: non_existent_file.txt", e);
}

在这段代码中,我们尝试打开一个不存在的文件,这会抛出 FileNotFoundException,这是一种可检查异常。

我们捕获这个异常后,并没有直接处理它,而是将其包装成一个 RuntimeException 再次抛出,这样做有时是为了简化上层代码的处理逻辑或者转换异常类型。同时保留了原始异常的原因信息,方便调试和追踪问题源头。

Java 面试题精选 文章被收录于专栏

无论你是准备面试,提升职场竞争力,还是单纯热爱 Java 编程。本专栏将为你呈现一系列精选的 Java 面试题,涵盖从基础到高级的各个层面,帮助你全面提升 Java 编程知识。

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务