活动地址:CSDN21天学习挑战赛
目录
一、Java异常(Exception)基本概念
总述:异常就是程序运行过程中出现了不正常现象导致程序的中断,异常处理是为了确保程序可以成功构建,而非因异常而中止退出。
1.1 异常的分类
错误Error | 硬件/操作系统的错误,即java程序语言不能解决的 | |||
---|---|---|---|---|
异常Exception | 运行时异常RuntimeException | 该类异常可以处理也可以不处理,但应尽量避免,如除数为0、数组下标越界等 | ArithmeticException | 不寻常算数异常 |
ArrayIndexOutOfBoundsException | 数组越界异常 | |||
ClassCastException | 类对象强迫转换异常 | |||
NullPointerException | 对象引用参考值为空null | |||
一般性异常 | 必须捕获处理,否则java程序将无法编译通过 | ClassNotFoundException | 找不到类或接口 | |
InterruptedException | 另一个线程中断当前线程 | |||
IOException | 输入输出访问异常 |
1.2 异常的处理方法
1)直接处理:通过try...catch块、finally块等捕获处理异常
2)异常抛出:将异常抛给上一层调用它的方法,由上一层方法进行处理、或继续向上一层抛出该异常
1.3 try/catch捕获异常
try...catch...语句块类似于if...elseif...的逻辑,判断可能存在异常的多种类型,并分别处理。在可能发生异常的地方编写如下异常捕获结构:
try {
//1、对可能产生异常的代码进行检视
//2、如果try代码块的某条语句产生了异常, 就立即跳转到catch子句执行, try代码块后面的代码不再执行
//3、try代码块可能会有多个受检异常需要预处理, 可以通过多个catch子句分别捕获
} catch (异常类型1 e1) {System.out.println("捕获异常:"+e1);
.....
//捕获异常类型1的异常, 进行处理
//在开发阶段, 一般的处理方式要么获得异常信息, 要么打印异常栈跟踪信息(e1.printStackTrace())
//在部署后, 如果有异常, 一般把异常信息打印到日志文件中, 如:logger.error(e1.getMessage());
} catch (异常类型2 e2) {
//捕获异常类型2的异常, 进行处理
//如果捕获的异常类型有继承关系, 应该先捕获子异常再捕获父异常
//如果没有继承关系, catch子句没有先后顺序
} finally {
//不管是否产生/捕获了异常, finally子句总是会执行
//一般情况下, 会在finally子句中释放系统资源
}
使用try/catch语句后,若存在异常(如:e1),程序会执行 对应catch块的命令(System.out.println("捕获异常:"+e1);.......),此时程序可成功构建,而非中途退出。
1.4 finally关键字的作用
有时,无论代码异常与否,我们都希望进行一些操作,如:关闭现在运行的窗口。
此时,可以在try/catch结构块后加上finally代码段,表示不管是否产生/捕获了异常, finally子句总是会执行。
1.5 抛出异常
1)语句格式:throw e(异常对象);
2)catch捕获某些异常之后,可能在这个子块中无法处理,此时可以修改对象属性后,将其抛给上层调用并处理。
示例:
package Exception;
public class Exception_04{
public static void main(String[] args) {
try {
except();//该函数执行后抛出e,传递到下一行代码去调用
}catch(Exception e) {
System.out.println("再次捕获到异常!!");
}
}
public static void except() {//定义的except()方法必须是静态的,才能被主函数静态引用
int i = 0;
String greeting [] = {
"Hello world !",
"No,I mean it !",
"HELLO WORLD !!"
};
while(i<4) {
try {
System.out.println(greeting[i]);
}catch(ArrayIndexOutOfBoundsException e) {//标明要捕获异常的类型
System.out.println("捕获异常:");
System.out.println(e);
throw e;
}finally {
System.out.println("Finally,i="+i);
}
i++;
}
}
}
二、 异常处理前后的运行结果对比
以数组越界的异常类型为例:
先正常写一个输出字符串的代码:
package Exception;
public class Exception_01{
public static void main(String[] args) {
int i = 0;
String greeting [] = {
"Hello world !",
"No,I mean it !",
"HELLO WORLD !!"
};
while(i<4) {
System.out.println(greeting[i]);
i++;
}
}
}
此时会报错,如下图所示:是由于该线程运行过程中,在索引i=3处越界。
此时在while循环中加入使用try/catch语句进行异常的捕获:
package Exception;
public class Exception_01{
public static void main(String[] args) {
int i = 0;
String greeting [] = {
"Hello world !",
"No,I mean it !",
"HELLO WORLD !!"
};
while(i<4) {
try {
System.out.println(greeting[i]);
}catch(ArrayIndexOutOfBoundsException e) {//标明要捕获异常的类型
System.out.println("捕获异常:");
System.out.println(e);
}finally {
System.out.println("Finally,i="+i);
}
i++;
}
}
}
运行得到:
由结果对比可得,此时对于下标越界的异常,代码会执行catch中相应的命令(这里是输出异常System.out.println(......);)。
该程序可以成功构建,而非因异常而中止退出 。