一、异常的背景
1.1、初识异常
其实在我们开发中,就是代码出现意外状况。影响到程序的运行。
其实,在我们接触代码开始,就一直在接触异常,只是从来没有分类。
这点在java中,更加明显。
现在我们就来基本了解一下异常。
算数异常 ArithmeticException
public static void main(String[] args) {
int a = 10;
System.out.println(a / 0);
}
数组越界异常 ArrayIndexOutOfBoundsException
public static void main(String[] args) {
int[] array = {
1,2,3,4,5};
for (int i = 0; i < 10; i++) {
System.out.println(array[i]);
}
}
空指针异常 NullPointerException
public static void main(String[] args) {
String str = null;
System.out.println(str.length());
}
所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制
关键字 “运行时”
有些错误是这样的, 例如将 System.out.println 拼写错了, 写成了 system.out.println. 此时编译过程中就会出错, 这是 “编译期” 出错.
而运行时指的是程序已经编译通过得到 class 文件了, 再由 JVM 执行过程中出现的错误
异常的种类有很多, 不同种类的异常具有不同的含义, 也有不同的处理方式
1.2、防御式编程
错误在代码中是客观存在的. 因此我们要让程序出现问题的时候及时通知程序猿. 我们有两种主要的方式
- LBYL: Look Before You Leap. 在操作之前就做充分的检查.
- EAFP: It’s Easier to Ask Forgiveness than Permission. “事后获取原谅比事前获取许可更容易”. 也就是先操作, 遇到
问题再处理
异常的核心思想就是 EAFP
1.3、异常的好处
下面,我们用伪代码演示一下开始一局王者荣耀的过程
LBYL 风格的代码(不使用异常)
boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;
return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;
return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;
return;
}
ret = 选择英雄();
if (!ret) {
处理选择英雄错误;
return;
}
ret = 载入游戏画面();
if (!ret) {
处理载入游戏错误;
return;
}
EAFP 风格的代码(使用异常)
try {
登陆游戏();
开始匹配();
游戏确认();
选择英雄();
载入游戏画面();
...
} catch (登陆游戏异常) {
处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}
......
对比两种不同风格的代码, 我们可以发现, 使用第一种方式, 正常流程和错误处理流程代码混在一起, 代码整体显的比较
混乱. 而第二种方式正常流程和错误流程是分离开的, 更容易理解代码
二、异常的基本用法
2.1、基本语法
try{
有可能出现异常的语句 ;
}[catch (异常类型 异常对象) {
} ... ]
[finally {
异常的出口
}]
- try 代码块中放的是可能出现异常的代码.
- catch 代码块中放的是出现异常后的处理行为.
- finally 代码块中的代码用于处理善后工作, 会在最后执行.
- 其中 catch 和 finally 都可以根据情况选择加或者不加
2.2、使用try-catch处理异常
代码示例1 不处理异常
public static void main(String[] args) {
int[] array = {
1,2,3,4,5};
System.out.println(array[10]);
}
代码示例2 处理异常
public static void main(String[] args) {
int[] array = {
1,2,3,4,5};
try{
System.out.println(array[10]);
System.out.println("asddfddf");
}catch(ArrayIndexOutOfBoundsException e