throws关键字
throws用于声明方法可能抛出的异常类型。
基本语法
方法声明throws
在方法签名后声明可能抛出的异常类型。
Java
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
// FileReader构造方法抛出IOException
}
声明多个异常
Java
public void processFile(String path) throws IOException, FileNotFoundException {
FileReader reader = new FileReader(path);
// 处理文件
}
throws作用
异常声明作用
throws告诉调用者该方法可能抛出哪些异常,调用者必须处理。
Java
// 方法声明throws
public void readFile() throws IOException {
FileReader reader = new FileReader("file.txt");
}
// 调用者必须处理
public void caller() {
try {
readFile(); // 调用throws方法
} catch (IOException e) {
// 处理异常
}
}
转移处理责任
throws将异常处理责任从方法内部转移到调用者。
Java
// 方法内部不处理,声明throws
public void connect() throws SQLException {
Connection conn = DriverManager.getConnection(url);
}
// 调用者决定如何处理
public void useDatabase() {
try {
connect();
// 使用数据库
} catch (SQLException e) {
// 调用者处理
System.out.println("数据库连接失败");
}
}
throws与检查型异常
强制处理检查型异常
检查型异常必须用try-catch处理或用throws声明。
Java
// 方式1:try-catch处理
public void method1() {
try {
FileReader reader = new FileReader("file.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
// 方式2:throws声明
public void method2() throws IOException {
FileReader reader = new FileReader("file.txt");
}
编译时检查
检查型异常未处理会编译失败。
Java
// 编译错误:未报告异常IOException
public void method() {
FileReader reader = new FileReader("file.txt");
}
// 必须添加try-catch或throws
throws与非检查型异常
非检查型异常可选声明
RuntimeException及其子类声明throws是可选的。
Java
// 可以声明,但非强制
public void divide(int a, int b) throws ArithmeticException {
int result = a / b;
}
// 也可以不声明
public void divide(int a, int b) {
int result = a / b; // 可能抛ArithmeticException
}
非检查型异常声明throws是冗余的,编译器不强制要求。
异常传播链
异常向上传播
throws让异常沿调用链向上传播,直到被处理。
Java
public void methodA() throws IOException {
methodB(); // 调用methodB
}
public void methodB() throws IOException {
methodC(); // 调用methodC
}
public void methodC() throws IOException {
FileReader reader = new FileReader("file.txt"); // 抛出点
}
// 最终调用者处理
public void main() {
try {
methodA();
} catch (IOException e) {
// 处理异常
}
}
throws与throw对比
throws与throw区别
| 特性 | throws | throw |
|---|---|---|
| 位置 | 方法签名声明 | 方法体内使用 |
| 作用 | 声明可能抛出的异常 | 实际抛出异常对象 |
| 后面内容 | 异常类型列表 | 异常对象 |
| 处理方式 | 转移给调用者 | 立即中断执行 |
示例对比
Java
// throws:声明异常
public void read() throws IOException {
FileReader reader = new FileReader("file.txt");
}
// throw:抛出异常
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负");
}
}
方法重写与throws
重写throws规则
子类重写方法throws范围不能超出父类。
Java
// 父类
class Parent {
public void method() throws IOException {
// ...
}
}
// 子类正确:throws范围相同或更小
class Child extends Parent {
@Override
public void method() throws IOException { // 相同
// ...
}
// 或不抛异常
@Override
public void method() { // 更小
// ...
}
}
// 子类错误:throws范围更大
class Wrong extends Parent {
@Override
public void method() throws Exception { // 编译错误
// IOException是Exception子类,范围扩大
}
}
重写规则总结
- 子类可以抛出与父类相同的异常
- 子类可以抛出父类异常的子类
- 子类可以不抛异常
- 子类不能抛出父类未声明的检查型异常
- 非检查型异常不受限制
使用场景
适合使用throws
- 调用者更适合处理异常
- 异常需要传播到上层统一处理
- 多层调用链统一处理
不适合使用throws
- 当前层可以处理异常
- 异常信息对当前层有意义
- main方法不建议throws(程序终止)
要点总结
- throws声明方法可能抛出的异常类型
- throws将异常处理责任转移给调用者
- 检查型异常必须用throws声明或try-catch处理
- 非检查型异常声明throws是可选的
- throws可声明多个异常类型
- 异常沿调用链向上传播直到被处理
- throws在方法签名,throw在方法体内
- 子类重写throws范围不能超出父类
- 适合调用者处理时使用throws
📝 发现内容有误?点击此处直接编辑