所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
异常类有两个主要的子类:IOException 类和 RuntimeException 类。
如下图:
捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}
示例:
public class ExcepTest {
public static void main(String[] args){
try {
int[] a = new int[2];
System.out.println(a[3]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
System.out.println(" Out of the block! ");
}
}
输出:
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 2
Out of the block!
Process finished with exit code 0
多重捕获块
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
多重捕获块的语法如下所示:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}
throws/throw 关键字
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
也可以使用 throw 关键字抛出一个异常.
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
示例:
public class className
{
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException
{
// Method implementation
}
//Remainder of class definition
}
finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
示例:
public class ExcepTest {
public static void main(String[] args){
int[] a = new int[2]; // 数组的定义不要放在try代码块内
try {
System.out.println(a[3]);
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}finally {
a[0] = 6;
System.out.println(a[0]);
}
}
}
输出:
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 2
6
Process finished with exit code 0
注意:
-
catch 不能独立于 try 存在。
-
在 try/catch 后面添加 finally 块并非强制性要求的。
-
try 代码后不能既没 catch 块也没 finally 块。
声明自定义异常
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
-
所有异常都必须是 Throwable 的子类。
-
如果希望写一个检查性异常类,则需要继承 Exception 类。
-
如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
可以像下面这样定义自己的异常类:
class MyException extends Exception{
}
以下实例是一个银行账户的模拟,通过银行卡的号码完成识别,可以进行存钱和取钱的操作。
InsufficientFundsException.java 文件代码:
// //自定义异常类,继承Exception类
public class InsufficientFundsException extends Exception {
//此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
private double amount;
// 构造函数
public InsufficientFundsException(double amount){
this.amount = amount;
}
// 获取差额
public double getAmount() {
return amount;
}
}
在下面的 CheckingAccount 类中包含一个 withdraw() 方法抛出一个 InsufficientFundsException 异常。
CheckingAccount.java 文件代码:
// 此类模拟银行账户
public class CheckingAmount {
// balance为余额,number为卡号
private double balance;
private int number;
//构造函数
public CheckingAmount(int number){
this.number = number;
}
// 存钱
public void deposit(double amount){
balance += amount;
}
// 取钱
public void withdraw(double amount) throws InsufficientFundsException {
if (amount <= balance){
balance -= amount;
}else {
double needs = amount-balance;
throw new InsufficientFundsException(needs);
}
}
// 返回余额
public double getBalance(){
return balance;
}
// 返回卡号
public int getNumber() {
return number;
}
}
下面的 BankDemo 程序示范了如何调用 CheckingAccount 类的 deposit() 和 withdraw() 方法。
BankDemo.java 文件代码:
public class BankDemo {
public static void main(String[] args){
CheckingAmount c = new CheckingAmount(101);
System.out.println("存500元");
c.deposit(500);
try {
System.out.println("取100元");
c.withdraw(100);
System.out.println("取600元");
c.withdraw(600);
}catch (InsufficientFundsException e){
System.out.println("抱歉,你的余额还差:"+e.getAmount() + "元");
e.printStackTrace();
}
}
}
运行程序 BankDemo,得到结果如下所示:
存500元
取100元
取600元
抱歉,你的余额还差:200.0元
InsufficientFundsException
at CheckingAmount.withdraw(CheckingAmount.java:21)
at BankDemo.main(BankDemo.java:10)
Process finished with exit code 0
每天学习一点点,每天进步一点点。