throw用于方法体内主动抛出异常对象,throws用于方法声明处声明可能抛出的异常类型;前者执行即中断流程,后者仅作编译期契约声明。

throw 和 throws 是 Java 异常处理中两个容易混淆但职责分明的关键字:前者是“动手抛”,后者是“提前打招呼”。用错位置或混用会导致编译失败或逻辑混乱,尤其在处理检查型异常(checked exception)时更需谨慎。
throw 是方法内部的主动抛出动作
它出现在方法体里,后面必须跟一个真实的异常对象(new 出来的实例),执行到这一行就会立刻中断当前方法,把异常往上抛。
- 只能抛一个异常对象,比如 throw new IllegalArgumentException("用户名不能为空")
- 抛出后,该行之后的代码不再执行,除非被 try-catch 捕获
- 既可用于运行时异常(RuntimeException 及其子类),也可用于检查型异常,但抛出检查型异常时,方法声明通常要配合 throws
- 常见于参数校验、业务规则拦截等场景,例如年龄小于 0 就 throw,分数超出 100 就 throw
throws 是方法签名上的异常声明承诺
它写在方法声明末尾,不抛异常,只是告诉调用者:“我这个方法可能会冒出这些异常,你得自己看着办。”
- 后面跟的是异常类型(类名),不是对象,比如 throws IOException, SQLException
- 可以声明多个异常,用逗号分隔;也可以不抛出任何异常,但声明了就必须处理(捕获或继续 throws)
- 主要用于检查型异常——比如 FileReader 构造可能触发 FileNotFoundException,就必须在方法上 throws 声明
- 如果调用一个 throws 方法,编译器会强制你处理:要么用 try-catch 包住,要么在当前方法也加上 throws
位置、对象和意图都不同
throw 在花括号里,操作的是 异常实例;throws 在小括号后、大括号前,操作的是 异常类型。一个是“我出事了”,一个是“我可能出事”。
立即学习“Java免费学习笔记(深入)”;
- throw 是具体行为,一执行就生效;throws 是契约说明,编译期检查,运行时不产生效果
- throw 常见于自定义校验逻辑;throws 多见于 I/O、数据库、网络等底层资源操作的方法声明
- 二者可共存:方法内用 throw 抛异常,方法头用 throws 声明该异常(尤其是检查型异常)
一个典型协作示例
比如读取配置文件并校验内容:
public void loadConfig(String path) throws FileNotFoundException {
File file = new File(path);
if (!file.exists()) {
throw new FileNotFoundException("配置文件不存在: " + path); // 主动抛出
}
// 后续读取逻辑...
}
这里 throws 告诉调用方“可能找不到文件”,而 throw 是真找不到时立即执行的动作。调用方必须处理 FileNotFoundException,否则编译不过。










