2135 字
约 7 分钟
6
第45章 Java throw和throws
2026-09-24
无标签
第45章 Java throw和throws
面包屑导航 章节标题 学习目标
学习目标
- 掌握throw关键字的语法和使用场景
- 理解throws关键字的作用和声明方式
- 学会区分throw和throws的不同用途
- 掌握异常的传播机制和处理策略
- 了解异常处理的最佳实践
- 学会设计合理的异常处理架构
throw关键字详解
throw关键字详解
throw关键字用于在程序中主动抛出异常。当程序检测到错误条件时,可以使用throw语句创建并抛出一个异常对象。
基本语法
// 语法格式
throw new ExceptionType("异常信息");
// 示例
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数: " + age);
}
throw的特点
主动抛出:程序员主动创建并抛出异常对象立即终止:执行到throw语句时,当前方法立即终止异常对象:throw后面必须跟一个异常对象实例任何异常:可以抛出任何Throwable类型的异常
throw使用示例
public class ThrowExample {
/**
* 验证年龄是否合法
*/
public static void validateAge(int age) {
if (age < 0) {
// 使用throw主动抛出异常
throw new IllegalArgumentException("年龄不能为负数: " + age);
}
if (age > 150) {
throw new IllegalArgumentException("年龄不能超过150岁: " + age);
}
System.out.println("年龄验证通过: " + age + "岁");
}
/**
* 计算平方根
*/
public static double calculateSquareRoot(double number) {
if (number < 0) {
throw new ArithmeticException("不能计算负数的平方根: " + number);
}
return Math.sqrt(number);
}
public static void main(String[] args) {
try {
validateAge(25); // 正常执行
validateAge(-5); // 抛出异常
} catch (IllegalArgumentException e) {
System.out.println("捕获异常: " + e.getMessage());
}
}
}
throws关键字详解
throws关键字详解
throws关键字用于在方法签名中声明该方法可能抛出的异常类型。它告诉调用者这个方法可能会抛出哪些异常,调用者必须处理这些异常或继续向上抛出。
基本语法
// 语法格式
public void methodName() throws ExceptionType1, ExceptionType2 {
// 方法体
}
// 示例
public void readFile(String filename) throws IOException {
// 可能抛出IOException的代码
}
throws的特点
声明异常:在方法签名中声明可能抛出的异常多个异常:可以声明多个异常类型,用逗号分隔强制处理:调用者必须处理或继续声明这些异常编译检查:编译器会检查异常是否被正确处理
throws使用示例
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ThrowsExample {
/**
* 读取文件内容
*/
public static String readFile(String filename) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(filename));
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append("\n");
}
reader.close();
return content.toString();
}
/**
* 解析日期字符串
*/
public static Date parseDate(String dateStr, String pattern) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
return formatter.parse(dateStr);
}
/**
* 处理多个异常的方法
*/
public static void performOperation(String operation)
throws IOException, ParseException, SQLException {
switch (operation) {
case "file":
readFile("test.txt");
break;
case "date":
parseDate("invalid-date", "yyyy-MM-dd");
break;
case "database":
connectDatabase("", "user", "pass");
break;
}
}
public static void main(String[] args) {
// 调用者必须处理异常
try {
String content = readFile("test.txt");
System.out.println("文件内容: " + content);
} catch (IOException e) {
System.out.println("文件操作异常: " + e.getMessage());
}
}
}
throw vs throws 对比
throw vs throws 对比
| 特性 | throw | throws |
|---|---|---|
| 位置 | 方法体内 | 方法签名中 |
| 作用 | 抛出异常 | 声明异常 |
| 数量 | 一次只能抛出一个 | 可以声明多个 |
| 语法 | throw + 异常对象 | throws + 异常类型 |
| 执行时机 | 运行时执行 | 编译时检查 |
| 后续代码 | 不会执行 | 正常执行 |
对比示例
public class ThrowVsThrowsExample {
/**
* 使用throw主动抛出异常的方法
*/
public static void validateScore(int score) {
// 使用throw主动抛出异常
if (score < 0 || score > 100) {
throw new IllegalArgumentException("分数必须在0-100之间: " + score);
}
System.out.println("分数有效: " + score);
}
/**
* 使用throws声明可能抛出异常的方法
*/
public static double safeDivide(double dividend, double divisor) throws ArithmeticException {
if (divisor == 0) {
throw new ArithmeticException("除数不能为零");
}
return dividend / divisor;
}
/**
* 同时使用throw和throws的方法
*/
public static String processText(String text, int maxLength)
throws IllegalArgumentException, RuntimeException {
// 参数验证,使用throw抛出异常
if (text == null) {
throw new IllegalArgumentException("文本不能为null");
}
if (maxLength <= 0) {
throw new IllegalArgumentException("最大长度必须大于0");
}
// 业务逻辑处理
if (text.length() > maxLength) {
if (maxLength < 10) {
throw new RuntimeException("文本太长且最大长度太小,无法处理");
}
return text.substring(0, maxLength) + "...";
}
return text;
}
}
异常传播机制
异常传播机制
当方法抛出异常时,异常会沿着调用栈向上传播,直到被捕获处理或到达程序顶层。
public class ExceptionPropagationExample {
/**
* 方法链中的异常传播示例
*/
public static void methodA(int value) throws Exception {
System.out.println("方法A开始执行");
methodB(value); // 调用可能抛出异常的方法
System.out.println("方法A执行完成");
}
public static void methodB(int value) throws Exception {
System.out.println("方法B开始执行");
methodC(value); // 继续传播异常
System.out.println("方法B执行完成");
}
public static void methodC(int value) throws Exception {
System.out.println("方法C开始执行");
if (value < 0) {
throw new Exception("方法C: 值不能为负数 " + value);
}
System.out.println("方法C执行完成,值: " + value);
}
public static void main(String[] args) {
try {
methodA(5); // 正常执行
methodA(-1); // 异常传播
} catch (Exception e) {
System.out.println("在main方法中捕获异常: " + e.getMessage());
}
}
}
💻 查看完整代码 - 在线IDE体验 异常处理最佳实践
异常处理最佳实践
异常处理原则
好的做法
// 尽早抛出异常
if (user == null) {
throw new IllegalArgumentException("用户不能为null");
}
// 提供有意义的异常信息
throw new IllegalArgumentException(
"年龄必须在0-150之间,当前值: " + age);
// 使用具体的异常类型
throw new FileNotFoundException("文件未找到: " + filename);
// 保留异常链
try {
// 一些操作
} catch (IOException e) {
throw new ServiceException("服务调用失败", e);
}
- 尽早抛出异常,尽晚捕获异常
- 提供有意义的异常信息
- 使用具体的异常类型
- 保留异常链,不丢失原始信息
- 合理使用检查异常和运行时异常
应该避免的做法
// 忽略异常
try {
riskyOperation();
} catch (Exception e) {
// 什么都不做 - 错误做法
}
// 异常信息不明确
throw new Exception("错误");
// 过度使用检查异常
public void setAge(int age) throws InvalidAgeException {
if (age < 0) throw new InvalidAgeException();
}
// 丢失异常信息
try {
operation();
} catch (SpecificException e) {
throw new RuntimeException("操作失败");
}
- 忽略异常或空的catch块
- 异常信息不明确或无意义
- 过度使用检查异常
- 丢失原始异常信息
- 捕获过于宽泛的异常类型
异常类型选择
异常类型选择指南
检查异常 vs 运行时异常检查异常(Checked Exception):必须在方法签名中声明或捕获处理,如IOException、SQLException运行时异常(Runtime Exception):不强制要求声明或捕获,如IllegalArgumentException、NullPointerException错误(Error):系统级错误,通常不应该捕获,如OutOfMemoryError、StackOverflowError
异常选择建议对于可恢复的错误,使用检查异常对于编程错误,使用运行时异常不要为简单的参数验证使用检查异常优先使用标准异常类型必要时创建自定义异常类
本章小结
本章小结
- throw关键字用于在程序中主动抛出异常,执行到throw语句时方法立即终止
- throws关键字用于在方法签名中声明可能抛出的异常,调用者必须处理这些异常
- throw后面跟异常对象,throws后面跟异常类型
- 异常会沿着调用栈向上传播,直到被捕获或到达程序顶层
- 应该尽早抛出异常,尽晚捕获异常,提供有意义的异常信息
- 合理选择异常类型:检查异常用于可恢复错误,运行时异常用于编程错误
- 保持异常链完整,不要丢失原始异常信息
第45章 Java throw和throws
https://clxhxhhr.top/posts/2990/ 评论
0 条
还没有评论,先写一条吧。