Java里常见运行时异常有哪些_Java异常类型汇总说明

最常见的运行时异常包括NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException、ClassCastException、NumberFormatException和IllegalArgumentException,它们均继承自RuntimeException,编译期不强制处理,因属可预防的逻辑错误而非外部不确定性。

Java里最常见的运行时异常,就是那些编译期不报错、但一运行就崩的“逻辑刺客”——它们都继承自 RuntimeException,编译器不管,全靠程序员自己盯。

哪些异常属于“不用 try-catch 也合法”的运行时异常?

这些异常在编译阶段完全不会提醒你,只有执行到那行代码才会抛出。它们本质是程序逻辑缺陷,比如传了 null、算错了下标、除以零。JVM 认为:这不该由框架兜底,而该由你写得更严谨。

  • NullPointerException:调用 null 对象的方法或访问其字段,如 str.length()str == null
  • ArrayIndexOutOfBoundsException:数组索引 >= array.length,如 arr[5]arr 长度只有 3
  • ArithmeticException:最典型是 / by zero,如 10 / 0
  • ClassCastException:强制转型失败,如 (String) new Integer(42)
  • NumberFormatException:字符串转数字失败,如 Integer.parseInt("abc")
  • IllegalArgumentException:方法收到非法参数,如 Arrays.asList(null)(某些实现会抛)

为什么编译器不强制处理这些异常?

因为它们大多反映的是**可预防的编码错误**,而非外部不确定性(比如文件是否存在、网络是否通畅)。强制加 try-catch 不仅冗余,还会掩盖真正该修复的 bug。

  • 加了 catch (NullPointerException e) 并不能让 str 变成非 null;它只是把崩溃延后,还可能掩盖空值来源
  • 频繁捕获 ArrayIndexOutOfBoundsException 往往说明你没做边界校验,或没用 for-each / List.size() 等更安全的方式遍历
  • RuntimeException 子类的设计哲学是:**修复源头,而不是包裹异常**

容易被误当成“编译异常”来处理的坑

新手常混淆两类异常,尤其看到 IDE 提示“unhandled exception”就本能加 try-catch——但注意:这个提示只对 检查型异常(checked exceptions) 出现,比如 IOExceptionSQLException;而上面列出的所有运行时异常,IDE 绝不会强制你捕获。

  • 误把 FileNotFoundException(编译异常)和 NullPointerException(运行异常)混为一谈:前者必须声明或捕获,后者完全可以不写任何异常处理
  • 在工具类中无差别 catch (Exception e),结果吞掉了本该暴露的 NullPointerException,导致后续逻辑静默失败
  • throws RuntimeException 声明方法抛出运行时异常——完全多余,语法合法但毫无意义,因为调用方根本不需要声明或捕获
public class RuntimeExample {
    public static void main(String[] args) {
        String s = null;
        // 编译通过 ✅ —— 但运行时抛出 NullPointerException
        System.out.println(s.length()); 

        int[] arr = {1, 2, 3};
        // 编译通过 ✅ —— 但运行时抛出 ArrayIndexOutOfBoundsException
        System.out.println(arr[10]); 
    }
}

真正关键的不是记住所有异常名,而是理解:运行时异常是代码质量的探针——它不报警,但一触发,就说明某处逻辑疏漏了。与其花时间写防御性 catch,不如用 Objects.requireNonNull()、提前判空、用集合 API 替代裸数组、单元测试覆盖边界值。