目录
一、异常的概念
二、常见异常
java异常体系结构:
三、异常分类
1、编译时异常(CompilationException):
2、运行时异常(RuntimeException):
四、异常的处理方法
1、事前防御型
2、事后认错型
五、编写异常throw(重点)
六、异常的捕获(重点)
1、 异常声明throws
2、try-catch捕获并处理(重点)
3、finally
通俗点儿讲:就是我们在编写代码时的异常(比如代码下面出现红色的波浪线)
IOException 输入输出流异常
FileNotFoundException 文件找不到的异常
ClassNotFoundException 类找不到异常
DataFormatException 数据格式化异常
NoSuchFieldException 没有匹配的属性异常
NoSuchMethodException 没有匹配的方法异常
SQLException 数据库操作异常
TimeoutException 执行超时异常
IOException:广泛的说,什么时候会有IOException ,比如你文件都不到的时候 ,你在做数据库操作的时候数据库底层出现问题 ,或者你系统IO出问题了 ,系统拿不到文件句柄 ,你说的读着读着突然被删了,你可以试试,书不定真可以 ,你可以看有多少IOExeption个子类,差不多就有多少种类型。
FileNotFoundException:注意,这里的找不到是在你的编译结果文件夹里面找不到,而不是在你的工程里面找不到,很多同学说自己工程里面有这个文件,为什么还要报这个异常?这个时候,你最好跑到你的编译文件放的文件夹下面,比如tomcat的webapps文件夹下面,找找你的工程对应的文件夹,看看那个里面有没有你的文件
ClassNotFoundException:属于编译时异常,是在classloader加载类的时候发现类不存在在类路径的时候报出的。
SQLException:比如SQL语句写错,访问的表不存在,连接数据库失败等。
通俗点儿讲:就是我们在执行代码时的异常(运行框会报出以下名字的异常)
ArrayIndexOutofBoundsException 数组越界异常
ClassCastException 类型转换异常
NullPointerException 空指针异常
IllegalAccessException 非法的参数异常
InputMismatchException 输入不匹配异常
通俗点儿讲:在操作之前就做充分的检查,例如:
boolean ret = false;
ret = 登陆游戏();
if (!ret) {
处理登陆游戏错误;
return;
}
ret = 开始匹配();
if (!ret) {
处理匹配错误;
return;
}
ret = 游戏确认();
if (!ret) {
处理游戏确认错误;
return;
}
优点:可以时时了解代码中的异常方便且快速找到异常位置并处理。缺陷:正常流程和错误处理流程代码混在一起 , 代码整体显的比较混乱,过程繁琐。(不加return的话,一旦出现一个异常,后面异常会一起抛出,分辨不清)
通俗点儿讲:就是先操作, 遇到问题再处理,例如:
try {
登陆游戏();
开始匹配();
游戏确认();
选择英雄();
载入游戏画面();
...
} catch (登陆游戏异常) {
处理登陆游戏异常;
} catch (开始匹配异常) {
处理开始匹配异常;
} catch (游戏确认异常) {
处理游戏确认异常;
} catch (选择英雄异常) {
处理选择英雄异常;
} catch (载入游戏画面异常) {
处理载入游戏画面异常;
}
上述代码意思是:try{}中编写的是可能出现的异常的代码,catch()中写异常的名字例如(NullPointerException、ArithmeticException等),catch(){}中写异常的处理。(不明白的话可以往下面看,有详细介绍try()和catch() )
优势:正常流程和错误流程是分离开的 , 程序员更关注正常流程,代码更清晰,容易理解代码异常处理的核心思想 。缺点:部分异常执行后需要及时处理,这个方式需要等待try{}中所有代码执行完成
throw new XXXException("异常产生的原因");
实例:实现一个获取数组中任意位置元素的方法。
public static int getElement(int[] array, int index){
if(null == array){
throw new NullPointerException("传递的数组为null");
}
if(index < 0 || index >= array.length){
throw new ArrayIndexOutOfBoundsException("传递的数组下标越界");
}
return array[index];
}
public static void main(String[] args) {
int[] array = {1,2,3};
getElement(array, 3);
}
结果:
传递的数组下标越界
要想处理异常必须要先捕获到异常
处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛 给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。
(扩展:如果方法的调用者还是没有处理异常,那么会交给方法调用者的调用者,就是一直在交给父类方法去处理,当没有任何方法处理异常时,会交给JVM处理,处理完程序终止)
语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{
}
实例:
public static void fun() throws NullPointerException{
int [] array =null;
System.out.println(array.length);
}
public static void main(String [] args){
fun();
}
结果:
NullpointerExcetion
语法格式:
try{
// 将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){
// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try
// 中抛出异常的基类时,就会被捕获到
// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码
}[catch(异常类型 e){
// 对异常进行处理
}finally{
// 此处代码一定会被执行到
}]
// 后序代码
// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行
// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行
注意:
1. []中表示可选项,可以添加,也可以不用添加
2. try中的代码可能会抛出异常,也可能不会
实例
public static void fun() throws NullPointerException{
int [] array =null;
System.out.println(array.length);
}
public static void main(String [] args){
try {
fun();
System.out.println("这句代码不执行");
}catch (NullPointerException e){
//System.out.println(e.getMessage()); // 只打印异常信息
//System.out.println(e); // 打印异常类型:异常信息
//e.printStackTrace(); // 打印信息最全面
System.out.println("异常处理");
}
System.out.println("程序结束");
}
结果:
异常处理
程序结束
public static void main(String[] args) {
try{
int[] arr = {1,2,3};
arr[100] = 10;
arr[0] = 10;
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}finally {
System.out.println("finally中的代码一定会执行");
}
System.out.println("如果没有抛出异常,或者异常被处理了,try-catch后的代码也会执行");
}
public class TestFinally {
public static int getData(){
Scanner sc = null;
try{
sc = new Scanner(System.in);
int data = sc.nextInt();
return data;
}catch (InputMismatchException e){
e.printStackTrace();
}finally {
System.out.println("finally中代码");
}
System.out.println("try-catch-finally之后代码");
if(null != sc){
sc.close();
}
return 0;
}
public static void main(String[] args) {
int data = getData();
System.out.println(data);
}
}
// 正常输入时程序运行结果:
100
finally中代码
100
// 下面程序输出什么?
public static void main(String[] args) {
System.out.println(func());
}
public static int func() {
try {
return 10;
} finally {
return 20;
}
}
A: 10 B: 20 C: 30 D: 编译失败