Java中运行时异常是Exception的子类,属非受检异常,编译器不强制捕获或声明;由程序逻辑错误引起,应通过编码规避而非try-catch兜底,常见类型包括NullPointerException、ArrayIndexOutOfBoundsException等。

Java中的运行时异常(RuntimeException)是Exception的子类,属于非受检异常(unchecked exception),编译器不强制要求捕获或声明。它们通常由程序逻辑错误引起,应在编码阶段主动规避,而非依赖try-catch兜底。
常见的RuntimeException类型及典型场景
以下是最常 encountered 的几种运行时异常,每种都附带触发条件和简明示例:
-
NullPointerException:访问null引用的字段、方法或数组元素。
例如:String s = null; s.length(); -
ArrayIndexOutOfBoundsException:数组下标小于0或大于等于数组长度。
例如:int[] a = {1}; a[5]; -
StringIndexOutOfBoundsException:字符串索引越界,本质是ArrayIndexOutOfBoundsException的子类。
例如:"abc".charAt(5); -
ClassCastException:非法的向下转型,且运行时类型不匹配。
例如:Object o = new Date(); String s = (String) o; -
ArithmeticException:算术运算异常,最常见的是整数除零。
例如:int x = 10 / 0; -
IllegalArgumentException:方法接收到不合法或不合适的参数。
例如:Integer.parseInt("abc");抛出 NumberFormatException(它是该异常的子类) -
IllegalStateException:对象处于不支持当前操作的状态。
例如:调用迭代器的next()前未调用hasNext(),或在Stream已消费后再次遍历。
为什么这些异常不用强制处理?
运行时异常的设计哲学是:它们反映的是程序缺陷,而非外部不确定性。比如空指针、越界、类型强转失败——这些问题本该在开发、测试阶段被发现并修复,而不是靠异常处理掩盖逻辑漏洞。
- 编译器不检查,避免代码充斥大量防御性catch,影响可读性与性能
- JVM在运行时检测并抛出,便于快速定位bug根源
- 鼓励开发者写更健壮的前置校验(如
if (obj != null)、if (index >= 0 && index )
如何正确应对运行时异常?
重点不在“捕获”,而在“预防”和“诊断”:
立即学习“Java免费学习笔记(深入)”;
- 对可能为null的引用,优先使用
Objects.requireNonNull()或Optional封装 - 数组/集合访问前做边界检查;使用增强for循环或Stream API降低手动索引风险
- 类型转换前用
instanceof判断(注意泛型擦除限制) - 方法入参校验统一放在开头,尽早失败(fail-fast),配合注解如
@NotNull+ Lombok或Spring Validation - 发生异常时,第一时间看
printStackTrace()或日志中的栈顶行——它指向真正出错的代码行,而非异常传播路径
自定义运行时异常也很常见
业务中常定义继承RuntimeException的异常类,例如OrderNotFoundException、InsufficientBalanceException。这类异常无需throws声明,可在任意层级直接throw,由全局异常处理器(如Spring的@ControllerAdvice)统一响应,保持业务代码简洁。










