JAVA基础第四章 Java异常和异常处理

4.0Java异常的引入

1.异常——程序不正常的行为或状态,即程序运行到某处时未按照原设计意愿进行。但语法错误和逻辑错误不是异常,对应着Java运行错误处理机制

异常的例子:int a = 5/0;数组越界访问;读取文件,结果该文件不存在

2.异常处理——处理异常

使程序回到安全状态;

允许用户保存结果,并以适当方式关闭程序;

(在操作系统层面上的对异常的处理:win98一旦出现错误直接蓝屏,所有正在写的代码、文档等等都不会保存;win7/10出现错误时一般是弹窗警告且不会影响其它没有异常的程序)


4.1异常分类

Throwable类:所有异常最顶端的父类

(1)Error类: JVM相关的异常——内部错误或者资源耗尽,由系统保留(不管)

(2)Exception类: 程序有关的异常,供应用程序使用,一般所说的异常是指Exception类及其子类

①Runtime Exception及其子类: 程序自身的错误

Runtime Exception类的子类称Unchecked Exception类(不受检的异常),是编译器不会辅助检查的、需程序员自己管的异常。以预先判定以避免为主。

例:5/0 ,空指针,数组越界,数字格式不对

②非Runtime Exception类及其子类:外界相关的错误

非Runtime Exception类及其子类称Checked Exception类(受检的异常),是编译器会辅助检查的异常,检查到会提醒,未处理则通不过编译。以发生异常后处理以避免为主。

例:打开一个不存在文件;加载一个不存在的类;连接一个不存在的数据库

注:IO Exception(输入输出异常)是非Runtime Exception的典型示例

4.2.1异常处理(一)

1.Java处理异常基本流程:①抛出(throw)异常:只管抛出,不一定在本方法内处理,至于到底谁去处理  ②会在运行时系统在调用栈中查找——从生成异常的方法开始进行回溯,直到找到:③捕获(catch)异常的代码

2.相关语句格式:

(1)抛出异常

           throw异常对象;

注:在程序中采用throw主动抛出异常时:在方法的内部,抛出异常采用throw关键字;在方法的声明中,声明抛出异常采用throws关键字

(2)捕获异常

try{

语句组

}catch(异常类名  异常形式参数名){

异常处理语句组;

}catch(异常类名  异常形式参数名){

异常处理语句组;

}finally{

异常处理语句组;

}

注:其中,catch语句可0至多个,可没有finally语句

3. Exception类——程序相关异常的最高父类

(1)构造方法

public Exception(); //默认无参构造方法

public Exception(String message);//有参构造方法1

Exception(String message, Throwable cause) ; //有参构造方法2,信息+底层原因

(2)普通方法

getMessage();//得到信息的getter方法

getCause();//得到底层原因的getter方法

printStackTrace();//该方法没有返回值,它的功能是完成一个打印操作,在当前的标准输出(一般就是屏幕显示)上打印输出当前例外对象的堆栈使用轨迹,也即程序先后调用并执行了哪些对象或类的哪些方法,使得运行过程中产生了这个异常对象。

4.多异常的处理:由于catch块的异常匹配是从上而下进行匹配,所以子类异常(小异常)要写在父类异常(大异常)的前面。小异常:一般是指具体的异常子类,如Arithmetic Exception;大异常:一般是泛指一种错误类型的异常父类,如Exception。

       5.受检的异常(非Runtime Exception类及其子类称Checked Exception类),要求明确进行语法处理:

    (1)要么捕(catch)

    (2)要么抛(throws):在方法签名后用throws xxxx来声明,这个声明表示该方法有抛出异常的可能

①当调用声明过抛出异常的方法时,仍然是要么捕要么抛,直至main方法。而在main方法内,仍然是要么捕要么抛,构成了一个严格体系。

②如果父类的抛出异常的方法被覆盖,那么覆盖它的子类方法要么抛出相同的异常、要么抛出子类异常。如果父类的方法抛出多个异常,那么重写的子类方法必须抛出那些异常类或其各子类异常。总之子类重写的方法所声明的异常,不能超出被覆盖的父类方法中所声明的异常范围。

4.2.2异常处理(二)

1.异常处理的目的:

(1)允许用户及时保存结果

(2)抓住异常,分析异常内容

(3)控制程序返回到安全状态

2. try-catch-finally: 一种在程序运行过程中,遇到异常时使代码正常继续向下执行的机制。

(1)结构(try 必有,catch 和finally至少有一个,catch可有多个):

try…catch

try…catch…finally

try…finally

①try: 实现业务的代码

②catch: 当try发生异常时,将立即跳跃到catch 代码执行,并不再返回到try语句。若无异常,跳过catch语句。

③finally: 当trycatch执行结束后,必须要执行finally

注: 即使catch内部再次发生异常时,也不影响finally的最终执行

(2)关于catch

①catch块可以有多个,每个都有相互不同的入口形参。当已发生的异常和某一个catch块中的形参类型一致,那么将执行该catch 块中的代码 。如果没有匹配的,catch则不会被触发。最后都进入 finally 块。

②进入catch块后,既再不会返回到try中发生异常的位置,更不会执行后续的catch块。即一个异常只能进入一个catch块。

(3)关于finally

①try结构中,只要有finally块,finally语句就肯定被执行(即使前面有break语句、return语句,即便try、catch内都发生了异常)
②try catch finally每个模块里面也允许发生异常,所以也可以在每个模块的内部继续写完整的try结构(不允许嵌套不完整的try结构,如双层try、双层catch)。

(4)三个例子:

  1. public class TryDemo {  
  2.   
  3.     public static void main(String[] args) {  
  4.       try  
  5.         {  
  6.             int a = 5/2//无异常,正常执行  
  7.             System.out.println("a is " + a);//无异常,正常执行  
  8.         }  
  9.         catch(Exception ex)//try内无异常,则catch语句被跳过  
  10.         {  
  11.             ex.printStackTrace();  
  12.         }  
  13.         finally//try内无异常,catch被跳过,最终执行finally  
  14.         {  
  15.             System.out.println("Phrase 1 is over");  
  16.         }  
  17.               
  18.         //try发生异常时,将立即跳跃到catch 代码执行,并不再返回到try语句。  
  19.         try  
  20.         {  
  21.             int a = 5/0//ArithmeticException,直接跳到catch语句  
  22.             System.out.println("a is " + a);//上一行出现异常,本行不被执行  
  23.         }  
  24.         catch(Exception ex)//从出现异常的行直接跳跃到该行执行  
  25.         {  
  26.             ex.printStackTrace();//无异常,正常执行  
  27.         }  
  28.         finally//try内有异常,直接跳跃到catch执行,最后执行finally  
  29.         {  
  30.             System.out.println("Phrase 2 is over");  
  31.         }  
  32.         
  33.         //catch内部再次发生异常时,也不影响finally的最终执行  
  34.         try  
  35.         {  
  36.             int a = 5/0//ArithmeticException,直接跳到catch语句  
  37.             System.out.println("a is " + a);//上一行出现异常,本行不被执行  
  38.         }  
  39.         catch(Exception ex)  
  40.         {  
  41.             ex.printStackTrace();//无异常,正常执行  
  42.             int a = 5/0//ArithmeticException,但程序不会在此处停止  
  43.             //而是直接跳跃到finally语句去执行  
  44.         }  
  45.         finally//catch内部再次发生异常时,不影响finally的最终执行  
  46.         {  
  47.             System.out.println("Phrase 3 is over");  
  48.         }  
  49.     }  
  50. }  


输出:

4. throws:当程序可能存在异常,但我处理不了时,那么就可以用throws来声明异常。

(1)调用带有throws checked exception的方法,要么catch这些异常,要么再次throws异常直至main方法,否则无法通过编译。
(2)用try-catch处理异常


输出:


(3)用try-catch处理异常 / 再次向外throws异常

4.3自定义异常类

1.简要复习:

(1)Throwable:所有异常的最顶端的父类,Exception类是所有程序相关异常类的父类。

(2)Exception类也继承自java.lang.Throwable,Error类与其在同一层级。但Error类异常一般是系统层面的,无需程序处理;程序只需要处理Exception。

2.Java在设计时提供了很多异常类,但有时仍不能满足需求,故需自定义异常类

3.自定义异常类时需继承Exception类或其子类,可以定义属性、方法(也可以重写父类的方法):

(1)继承自非Runtime Exception类及其子类:新定义的异常类就是Checked Exception

(2)继承自Runtime Exception类及其子类: 新定义的异常类就是Unchecked Exception的子类

4.自定义异常重点在构造函数

(1)调用父类Exception的message构造函数

(2)可以自定义自己的成员变量

5.通过下例理解自定义异常如何工作:

(1)MyException.java

  1. public class MyException extends Exception {      
  2.     //定义两个成员变量  
  3.     private String returnCode ;  //异常对应的返回码  
  4.     private String returnMsg;  //异常对应的描述信息  
  5.       
  6.     //默认无参构造函数  
  7.     public MyException() {  
  8.         super();//调用父类无参构造方法  
  9.     }  
  10.   
  11.     //有参构造函数1  
  12.     public MyException(String returnMsg) {  
  13.         super(returnMsg);//调用父类的参数列表为returnMsg的构造方法  
  14.         this.returnMsg = returnMsg;  
  15.     }  
  16.   
  17.     //有参构造函数2  
  18.     public MyException(String returnCode, String returnMsg) {  
  19.         super();//调用父类无参构造方法  
  20.         this.returnCode = returnCode;  
  21.         this.returnMsg = returnMsg;  
  22.     }  
  23.       
  24.     //两个getter方法  
  25.     public String getReturnCode() {  
  26.         return returnCode;  
  27.     }  
  28.     public String getreturnMsg() {  
  29.         return returnMsg;  
  30.     }  

(2)MyExceptionTest.java

  1. public class MyExceptionTest {  
  2.     //在方法的内部,抛出异常采用throw关键字;在方法的声明中,声明抛出异常采用throws关键字  
  3.     public static void testException() throws MyException {    
  4.        throw new MyException("10001""The reason of myException");    
  5.     }    
  6.       
  7.     //调用有异常的方法,要么try-catch处理异常,要么让再次throws异常直至main方法  
  8.     public static void main(String[] args)  {  
  9.         try {  
  10.             MyExceptionTest.testException();  
  11.         } catch (MyException e) {  
  12.             e.printStackTrace();  
  13.             System.out.println("returnCode:"+e.getReturnCode());  
  14.             System.out.println("returnMsg:"+e.getreturnMsg());  
  15.         }  
  16.     }  
  17. }  

6. 重抛异常及异常链接:对于异常,不仅要进行捕获处理,有时候还需将此异常进一步传递给调用者,以便让调用者也能感受到这种异常。这时可以在catch语句块或finally语句块中采取以下三种方式:

(1)将当前捕获的异常再次抛出:

throw e;

(2)重新生成一个异常,并抛出,如:

throw new Exception("some message");

(3)重新生成并抛出一个新异常,该异常中包含了当前异常的信息,如:

throw new Exception("some message",e) ;  //可用e.getCause() 来得到内部异常

注:本文由H同志编写,欢迎批评指正、交流探讨。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.yh21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值