【Java语言基础】异常处理机制

异常处理的基础知识

即使是有经验的程序员,也难免出现编程错误。

编程错误分类

  1. 编译错误(compilation error)
    1. 原因:没有遵循语言的规则
    2. 解决方法:由编译程序检查发现
  2. 逻辑错误(logic error)
    1. 原因:程序没有按照预期的方案执行
    2. 解决方法:利用调试技巧可以解决此类错误
  3. 运行时错误(runtime error)
    1. 原因:在程序运行过程中,出现了不可能执行的操作
    2. 解决方法:异常处理

运行时错误(runtime error)

在程序运行时出现一些非正常的现象被称为运行时错误,如除数为0,数组下标越界,文件不存在,内存不够用等等0

分类:根据错误性质将运行时错误分为两类

  • 致命性的错误
    例:程序进入了死循环,递归无法结束,内存溢出等,这些运行错误是致命性的错误,只能在编程阶段解决,运行时程序本身无法解决,只能依靠其他程序干预,否则会一直处于非正常状态。
    错误处理一般由系统承担,语言本身不提供错误处理机制。
  • 非致命性的异常
    例:除数为0,操作数超出数据范围,文件并不存在,欲装入的类文件丢失,网络连接中断等,这类现象称为非致命性的异常。
    是可以检测和处理的,所以产生了相应的异常处理机制。

异常处理的类层次

Java中预定义了很多异常类,每个异常类代表一种运行错误

  • Error:灾难性故障,由Java虚拟机生成并抛出给系统。通常,Java程序不对错误进行处理。
  • Exception:是用户程序能够捕捉到的“异常”情况,由Java程序抛出和处理。
常用的Exception类的子类:
异常类 描述
NullPointerException 空指针异常
ArrayIndexOutOfBoundsException 数组越界访问异常
ClassNotFoundException 试图访问一个根本不存在的类
IOException 输入/输出异常
NumberFormatException 错误的类型转换异常
ArrayStoreException 当向数组存入错误类型数据时
ArithmeticException 除数为0的算数异常

未被捕获“异常”

“异常”对象是Java运行时堆某些“异常”情况作出反应而产生的。如果不处理“异常”会有什么样的情况发生?

public class _519test {
    public static void main(String[] args) {
    	//当执行到该语句时,系统检测到被0除,构造一个“异常”对象来发异
        int a = 4 / 0;
    }
}

程序没有提供任何处理异常的异常处理程序,所以该异常被Java运行时系统的默认处理程序捕获,显示一个描述异常的字符串,打印异常发生出的堆栈轨迹并且终止程序。

异常处理机制

Java提供了异常处理机制,通过面向对象的方法来处理异常。

  • 在程序运行的过程中,如果发生了异常,则该程序(或虚拟机)生成一个代表该异常类的对象(包含该异常的详细信息),并把交给运行时系统;
  • 运行时系统从生成对象的代码开始,沿方法的调用栈逐层回溯查找,直到找到包含相对应处理代码的方法,并把异常对象交给该方法,来处理这一异常。

异常捕获

  1. 发现异常的代码“抛出”异常
  2. 运行时系统“捕获”异常
  3. 由程序员编写的相应代码“处理”异常

使用方法

使用try-catch-finally语句捕获和处理异常
格式

try{
	//可能产生异常的语句
}
catch(异常类 变量){
	//异常处理代码
}
[finally{
	//必须执行的代码,可有可无
}]

try语句块

  • 将程序只能可能出现异常的代码放入try块中。
  • 当try块中有语句引发异常时,系统将不再执行try块中未执行的语句,而执行匹配的catch块。
  • 如果try块中没有语句引发异常,则程序执行完try块中的语句后不执行catch块中的,即跳过catch语句,继续执行后面的程序。

catch块

  • 每个try语句后面必须伴随一个或多个catch语句,用于捕捉try语句块所产生的异常并作相应的处理。
  • catch自居的目标是解决“异常”情况,并像没有出错一样继续运行。
    例如:
try{
	int a = 4 / 0;
}catch(ArithmeticException e){
	System.out.println(e.toString());
}

注意:
一个try和它的catch语句组成了一个单元。catch字句的范围限制于try语句块中的语句。一个catch语句不能捕获另一个try声明所引发的异常(除非是嵌套的try语句情况)。被try保护的语句声明必须在一个大括号内,try语句块不能单独使用。

多个catch块

一个catch块只能处理一类异常,当try块中的与剧组可能抛出多种异常时,就需要有多个catch来分别处理各种异常。

  • 一个异常对象能否被一个catch块接收主要看该异常对象与catch块中声明的异常类的匹配情况,当它们满足下面条件中的任一条时,异常对象将被接收:
    • 异常对象是catch块中声明的异常类的实例;
    • 异常对象是catch块中声明的异常类的子类的实例;
    • 异常对象实现了catch块中声明的异常类的接口。
  • 当使用多个catch块时,需要注意catch子句排列顺序**–先特殊到一般,**也就是子类在父类前面。如果子类在父类后面,子类将永远不会到达。

try语句的嵌套

一个try语句可以在另一个try块内部----try语句的嵌套

  • 每次进入try语句,异常的前后关系都会被压入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。
  • 这个过程将继续直到一个catch语句匹配后,或者是直到所有的嵌套try语句被检查耗尽。
  • 如果没有catch语句匹配,Java的运行时系统将处理这个异常。

未完…


笔记源于上课老师的PPT

猜你喜欢

转载自blog.csdn.net/lolly1023/article/details/106219931
今日推荐