Java异常处理与断言:提升程序可靠性的关键技术
发布时间: 2025-08-17 02:24:56 阅读量: 1 订阅数: 6 

# Java 异常处理与断言:提升程序可靠性的关键技术
## 1. Java 断言概述
Java 断言是一种用于检测程序中逻辑错误的语言特性。虽然在简单的类中使用断言可能看起来帮助不大,但当程序逻辑变得复杂且类的数量增加时,断言的真正优势就会显现出来。
### 1.1 断言示例:银行账户类
以下是一个包含逻辑错误的银行账户类示例:
```java
class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
balance = initialBalance;
}
public void deposit(double amount) {
double oldBalance = balance;
balance -= amount;
assert balance > oldBalance;
}
public void withdraw(double amount) {
double oldBalance = balance;
balance -= amount;
assert balance < oldBalance;
}
public double getBalance() {
return balance;
}
}
```
在这个类中,`deposit` 和 `withdraw` 方法使用了 `assert` 语句。`assert` 语句的语法为:
```java
assert <boolean expression>;
```
当执行该语句时,`<boolean expression>` 会被求值。如果结果为 `true`,程序将继续正常执行;否则,将抛出一个 `AssertionError`(`Error` 的子类)。
### 1.2 运行包含断言的程序
要运行包含断言功能的程序,需要在运行时指定 `-ea` 选项,例如:
```bash
java -ea Ch8TestAssertMain
```
如果不提供 `-ea` 选项,程序将在不检查断言的情况下执行。在开发和测试程序时,可以启用断言;而在程序完全开发和测试完成后,可以禁用断言,因为检查所有断言可能会带来一定的性能开销。
### 1.3 自定义错误消息
可以使用 `assert` 语句的第二种形式来提供自定义错误消息,语法如下:
```java
assert <boolean expression> : <expression>;
```
`<expression>` 的值将作为参数传递给 `AssertionError` 类的构造函数,作为抛出错误的详细消息。例如,修改 `deposit` 方法如下:
```java
public void deposit(double amount) {
double oldBalance = balance;
balance -= amount;
assert balance > oldBalance : "Serious Error -- balance becomes less after deposit";
}
```
这样,当断言失败时,将显示自定义的错误消息。
### 1.4 断言类型
- **后置条件断言**:检查方法执行后必须为真的条件,如上述 `deposit` 和 `withdraw` 方法中的断言。
- **前置条件断言**:检查方法执行前必须为真的条件。
- **控制流不变式**:确保程序在正常运行时控制流始终遵循特定的规则。例如,在以下 `switch` 语句中:
```java
switch (residenceType) {
case COMMUTER:
totalFee = tuition + parkingFee;
break;
case DORM_RESIDENT:
totalFee = tuition + roomAndBoard;
break;
default:
assert false: "Value of residenceType is invalid. Value = " + residenceType;
}
```
这个 `switch` 语句假设每个学生要么是通勤生,要么是宿舍居民。如果 `residenceType` 的值不是 `COMMUTER` 或 `DORM_RESIDENT`,则会抛出断言错误。
### 1.5 断言与异常的区别
断言和异常机制都旨在提高程序的可靠性,但它们的使用场景不同。断言主要用于检测内部编程错误,而异常用于通知客户端程序员类的使用不当。
例如,以下代码错误地使用了断言来确保参数的有效性:
```java
public void withdraw(double amount) {
assert amount > 0;
double oldBalance = balance;
balance -= amount;
assert balance < oldBalance;
}
```
正确的做法是使用异常来处理参数的有效性检查:
```java
public void withdraw(double amount) throws IllegalArgumentException {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
double oldBalance = balance;
balance -= amount;
assert balance < oldBalance;
}
```
## 2. 示例开发:无钥匙进入系统
### 2.1 问题描述
开发一个模拟宿舍安全无钥匙进入系统的程序。在宿舍入口大厅,居民需要输入姓名、房间号和密码。输入有效数据后,系统将解锁通往宿舍生活区的内门。
### 2.2 整体计划
为了提供一个完整的系统,需要编写两个独立的程序:一个是用于添加、删除和更新居民信息的管理模块,另一个是与居民交互的用户模块。这里主要实现用户模块。
### 2.3 涉及的类
- **Resident 类**:维护单个宿舍居民的信息。该类必须实现 `Serializable` 接口,因为居民对象需要保存到文件中。
```java
import java.io.*;
class Resident implements Serializable {
private String name;
private String room;
private String password;
public Resident() {
this("unassigned", "000", "@13&");
}
public Resident(String name, String room, String pwd) throws IllegalArgumentException {
setName(name);
setRoom(room);
setPassword(pwd);
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public String getRoom() {
return room;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String pwd) {
int length = pwd.length();
if (length < 4 || length > 8) {
throw new IllegalArgumentException();
} else {
this.password = pwd;
}
}
public void setRoom(String room) {
this.room = room;
}
}
```
- **Dorm 类**:管理居民对象列表,支持添加、删除、检索居民信息,以及将列表保存到文件或从文件中读取列表。
```java
import java.io.FileNotFoundException;
import java.io.IOException;
class Dorm {
public Dorm() {
}
public Dorm(String filename) throws FileNotFoundException, IOException {
}
public void openFile(String filename) throws FileNotFoundException, IOException {
}
public void saveFile(String filename) throws IOException {
}
public void add(Resident resident) throws IllegalArgumentException {
}
public void delete(String name) {
}
public Resident getResident(String name) {
return null;
}
public String getResidentList() {
return "";
}
}
```
- **Door 类**:模拟门的打开操作。
```java
import javax.swing.JOptionPane;
class Door {
public Door() {
}
public void open() {
JOptionPane.showMessageDialog(null, "Door is opened.");
}
}
```
### 2.4 用户模块开发步骤
#### 2.4.1 步骤 1:定义 Resident 类并探索 Dorm 类
首先,需要根据规范实现 `Resident` 类。然后,使用一个骨架程序来测试 `Dorm` 类的操作。
```java
import javax.swing.*;
import java.io.*;
import java.util.Scanner;
class Ch8EntranceMonitor {
private Dorm
```
0
0
相关推荐









