Java throw与throws #
一、throw关键字 #
1.1 概念 #
throw用于手动抛出异常对象。
1.2 基本语法 #
java
throw new 异常类型("异常信息");
1.3 使用示例 #
java
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在0-150之间");
}
this.age = age;
}
1.4 抛出不同类型异常 #
java
// 抛出运行时异常
public void checkNotNull(Object obj) {
if (obj == null) {
throw new NullPointerException("对象不能为空");
}
}
// 抛出检查异常
public void readFile(String path) throws FileNotFoundException {
if (path == null) {
throw new FileNotFoundException("文件路径不能为空");
}
}
二、throws关键字 #
2.1 概念 #
throws用于声明方法可能抛出的异常。
2.2 基本语法 #
java
返回类型 方法名(参数列表) throws 异常类型1, 异常类型2 {
// 方法体
}
2.3 使用示例 #
java
public void readFile(String path) throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream(path);
// 读取操作
}
2.4 声明多个异常 #
java
public void copyFile(String src, String dest)
throws FileNotFoundException, IOException {
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest)) {
// 复制操作
}
}
三、throw与throws区别 #
| throw | throws |
|---|---|
| 抛出异常对象 | 声明异常类型 |
| 在方法体内使用 | 在方法签名上使用 |
| 只能抛出一个异常 | 可以声明多个异常 |
| 抛出异常后方法结束 | 只是声明,不处理 |
3.1 对比示例 #
java
// throw:抛出异常
public void method1() {
throw new RuntimeException("错误");
}
// throws:声明异常
public void method2() throws IOException {
// 可能抛出IOException
}
// 组合使用
public void method3() throws IllegalArgumentException {
if (invalid) {
throw new IllegalArgumentException("参数无效");
}
}
四、异常传递 #
4.1 异常链 #
java
public void method1() throws Exception {
method2();
}
public void method2() throws Exception {
method3();
}
public void method3() throws Exception {
throw new Exception("原始异常");
}
4.2 异常处理传递 #
java
public void outer() {
try {
inner();
} catch (IOException e) {
System.out.println("捕获到异常: " + e.getMessage());
}
}
public void inner() throws IOException {
throw new IOException("内部异常");
}
五、重写方法的异常声明 #
5.1 规则 #
- 子类方法可以抛出与父类相同的异常
- 子类方法可以抛出父类异常的子类
- 子类方法可以不抛出异常
- 子类方法不能抛出父类没有的检查异常
5.2 示例 #
java
class Parent {
public void method() throws IOException { }
}
class Child extends Parent {
// 正确:抛出相同异常
@Override
public void method() throws IOException { }
// 正确:抛出子类异常
// @Override
// public void method() throws FileNotFoundException { }
// 正确:不抛出异常
// @Override
// public void method() { }
// 错误:抛出父类没有的检查异常
// @Override
// public void method() throws SQLException { }
// 正确:可以抛出运行时异常
// @Override
// public void method() throws RuntimeException { }
}
六、最佳实践 #
6.1 合理选择异常类型 #
java
// 参数校验:使用运行时异常
public void setName(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("姓名不能为空");
}
this.name = name;
}
// 业务异常:使用检查异常
public void withdraw(double amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException("余额不足");
}
balance -= amount;
}
6.2 提供有意义的异常信息 #
java
// 不推荐
throw new IllegalArgumentException("错误");
// 推荐
throw new IllegalArgumentException("年龄 " + age + " 不在有效范围内(0-150)");
6.3 保留原始异常 #
java
public void loadData() throws DataLoadException {
try {
readFromFile();
} catch (IOException e) {
throw new DataLoadException("数据加载失败", e);
}
}
6.4 早失败 #
java
public void process(String input) {
// 尽早检查和抛出异常
if (input == null) {
throw new IllegalArgumentException("输入不能为空");
}
if (input.isEmpty()) {
throw new IllegalArgumentException("输入不能为空字符串");
}
// 正常处理
doProcess(input);
}
七、总结 #
| 关键字 | 用途 | 位置 |
|---|---|---|
| throw | 抛出异常对象 | 方法体内 |
| throws | 声明异常类型 | 方法签名 |
throw与throws要点:
- throw用于抛出异常对象
- throws用于声明方法可能抛出的异常
- 检查异常必须处理或声明
- 运行时异常可选处理
- 重写方法时异常声明有规则限制
最后更新:2026-03-26