1.1常见的异常
1. 算术异常
除数不能为0
System.out.println(999 / 0);
//报错
Exception in thread "main" java.lang.ArithmeticException: / by zero
2.数组越界
超过数组的下标范围
int[] arr = {1,2,3,4,5};
System.out.println(arr[999]);
// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 999
3.空指针异常
数组为空,指向空位置则为空指针异常
int[] arr = null;
System.out.println(arr.length());
//报错:
Exception in thread "main" java.lang.NullPointerException
java的异常有很多种,主要分为ERROR错误和Exceptinn异常,题目都属于Throwable
ERROR错误属于虚拟机都无法解决的错误,例如JVM内存耗尽等,程序直接崩溃
Exception异常是我们可以解决的异常,一般我们进行处理后程序都可以正常运行。
1.2异常的分类
1.2.1编译错误
在程序编译的时候就发成错误,无法通过编译,也称为受查异常
1.2.2运行错误
编译通过后程序在运行的时候发生异常,称作运行异常,也称为非受查异常
RuntimeException中的异常都属于非受查异常
异常的分类:
其中RuntimeException异常包括:
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常
1.3异常的处理
1.3.1防御性编程
1.事前防御:
缺点:正常的流程和发生错误的处理放在一起,显得代码比较冗杂
boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;
return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;
return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;
return;
}
ret = 选择英雄();
if (!ret) {
处理选择英雄错误;
return;
}
ret = 载入游戏画面();
if (!ret) {
处理载入游戏错误;
return;
}
2.事后处理型
正常流程和异常处理是分开写的,思路更加清晰,显得代码更加整洁
try {
登陆游戏();
开始匹配();
游戏确认();
选择英雄();
载入游戏画面();
...
} catch (登陆游戏异常) {
处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}
1.4异常的抛出
在java中,我们可以通过throw来抛出一个异常,将错误信息告知给程序员。
throw new XXXException("异常产生的原因");
例如当数组下标越界的时候我们可以参考如下代码尽心异常的抛出:
public static int getvalue(int[] array, int index){
//抛出异常
if(index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");
}
return array[index];
}
注意事项:
1. throw必须写在方法内部
2. 抛出的对象必须是Exception 或者 Exception 的子类对象
3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5. 异常一旦抛出,其后的代码就不会执行
1.5异常的捕获
1.5.1throws
当前方法不用来处理异常,而是提醒程序员来处理异常
语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{
}
注意事项:
1. throws必须跟在方法的参数列表之后
2. 声明的异常必须是 Exception 或者 Exception 的子类
3. 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型 具有父子关系,直接声明父类即可。
4. 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出(将光标放在抛出异常方法上,可以alt + Insert 快速 处理)
1.5.2try-catch
throws并没有对异常进行处理,只是将其抛出,如果需要对其进行处理,那就需要用到try-catch
语法格式:
try{
// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){
// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类
时,就会被捕获到
// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
}[catch(异常类型 e){
// 对异常进行处理
}finally{
// 此处代码一定会被执行到
}]
// 后序代码
// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行
// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行
注意:
1. []中表示可选项,可以添加,也可以不用添加
2. try中的代码可能会抛出异常,也可能不会