认识异常

一、异常的概念和体系结构

1、异常的概念

在Java中,将程序执行过程中发生的不正常行为称为异常,常见的有算术异常,数组越界异常,空指针异常

2、异常的体系结构

从上图中可以看到:
1.Throwable:是异常体系的顶层类,其派生出两个重要的子类,Error和Exception
2.Error:指的是Java虚拟机无法解法的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表:StackOverflowError和OutOfMemoryError,一旦发生无力回天。
3.Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说的异常就是Exception。

3.异常的分类

分为编译时异常(受检查异常)和运行时异常(非受检查时异常)

二、异常的处理

1、防御式编程

★LBYL:在操作前就做充分的检查,例如:

  boolean ret=输入密码();

  if(!ret){

      处理输入密码错误;

      return;

}

  ret=选择功能();

  if(!ret){

       处理选择功能错误;

       return;

  }

.........

缺陷:正常流程和错误处理流程代码混在一起,代码整体显得比较混乱。

★EAFP:先操作,遇到问题在处理,例如:

try{

    输入密码;

    选择功能;

    .......

}catch(输入密码异常){

  处理密码异常;

}catch(选择功能异常){

  处理功能异常;

}.......

在Java中,异常处理主要的五个关键字:throw,try,catch,final,throws.

2.异常的抛出

在Java中,借助throw关键字,跑出一个指定的异常对象,将错误信息告知给调用者,具体语法:

  throw newXXXException(“异常产生的原因”);

例如:

throw newArrayindexOutOfBoundsException(“传递的数组下标越界”);

注意:

1.throw必须写在方法体内部。
2. 抛出的对象必须是Exception 或者 Exception 的子类对象。
3.如果抛出的是RunTimeException或者RunTimeException的子类,则可以不用处理,直接交给JVM来处理。
4.如果抛出的是编译时异常,用户必须处理,否则无法通过编译。
5.异常一旦抛出,其后的代码就不会执行。

3、异常的捕获

异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws以及try-catch捕获处理。


◆ 异常声明throws

处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。


语法格式:
修饰符 返回值类型 方法名(参数列表)throws异常类型1,异常类型2...{

}
需求:加载指定的配置文件config.ini


注意:

▲throws必须在方法的参数列表之后。

▲声明的异常必须是Exception或者Exception的子类。

▲方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。

▲调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出。

◆try-catch捕获并处理

throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,如果真正要对异常进行处理,就需要try-catch。

语法格式:
try{
   //将可能出现异常的代码放在这里
}catch(要捕获的异常类型 e){
   // 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类时,就会被捕获到
    //对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码

    //try中可能会抛出多个不同的异常对象,则必须使用多个catch来捕获
}[catch(异常类型 e){
    //对异常进行处理
}finally{
    //此处代码一定会被执行到

}]

★[]中表示可选项,可以添加,也可以不用添加。

★try中的代码可能会抛出异常,也可能不会。try块内抛出的异常位置之后的代码将不会被执行。

★如果异常之间具有父子关系,一定是子类异常在前catch,父类异常在后catch。

可以通过Exception类是所有异常类的父类,因此可以用这个类型表示捕捉所以异常(不推荐)

◆finally

有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源:网络连接、数据库连接、IO流等,在程序正常或者异常退出时,必须要对资源进进行回收。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题的。

finally中的代码一定会执行的,一般在finally中进行一些资源清理的扫尾工作。

语法格式:
try{
   //可能会发生异常的代码
}catch(异常类型 e){
   //对捕获到的异常进行处理
}finally{
   //此处的语句无论是否发生异常,都会被执行到

}
//如果没有抛出异常,或者异常被捕获处理了,这里的代码也会执行

4、异常的处理流程

◇程序先执行 try中的代码。
◇如果 try中的代码出现异常,就会结束tr中的代码,看和catch中的异常类型是否匹配。

◇如果找到匹配的异常类型,就会执行catch中的代码。
◇如果没有找到匹配的异常类型,就会将异常向上传递到上层调用者。
◇无论是否找到匹配的异常类型,finally中的代码都会被执行到(在该方法结束之前执行).·如果上层调用者也没有处理的了异常,就继续向上传递。
◇一直到main方法也没有合适的代码处理异常,就会交给JVM来进行处理,此时程序就会异常终止。

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值