150 likes | 325 Views
包、异常与输入输出 3. 本单元教学内容. Java 异常的分类及异常类的层次结构 自定义异常 掌握 throw 关键字的用法. 异常分类. Error 异常. Error 异常 :运行时间出现的系统内部的错误以及资源耗尽等情况。 如:虚拟机内部发生错误、电源断电引起的异常中止等。 特点 :这类异常性质严重,本身难以控制,且恢复可能性极小,意义不大。 Java 不要求对这类异常进行必要的控制,编译期也不对这类异常进行检测。. RuntimeException 异常.
E N D
本单元教学内容 • Java异常的分类及异常类的层次结构 • 自定义异常 • 掌握throw关键字的用法
Error异常 • Error异常:运行时间出现的系统内部的错误以及资源耗尽等情况。 • 如:虚拟机内部发生错误、电源断电引起的异常中止等。 • 特点:这类异常性质严重,本身难以控制,且恢复可能性极小,意义不大。 • Java不要求对这类异常进行必要的控制,编译期也不对这类异常进行检测。
RuntimeException异常 • RuntimeException及其子类描述的异常,一般是由于编程错误引起的异常。如:错误的造型、数组越界存取、空指针访问等。 • 特点:完全可以通过改进程序加以克服,且数目很大。 • Java对这种异常的处理:编译时,不对这类异常进行检测;运行时,会自动在异常发生处生成相应的异常的对象,并由系统默认的异常处理器处理(通常输出错误信息及错误地点)。 • 应用程序可以对其进行捕获处理(但不提倡)。
运行环境引发的异常 • 运行环境引发的异常。 • 如:网络不通,文件找不到等。 • 特点:只要运行环境正常,程序是可以正常运行的。 • Java要求对这类异常进行必要的控制。
试一试 • class MyMath{ • public int devide(int x,int y) throws ArithmeticException{ • int result=x/y; • return result; • } • } • class MyMathTest{ • public static void main(String[] args){ • MyMath mobj; • mobj=new MyMath(); • int result; • result=mobj.devide(3,0); • System.out.println("the result is " + result); • } • } 将抛出的异常由Exception改为ArithmeticException 调用者没有对抛出的异常进行处理,编译能通过吗?
检查和非检查型异常 • 非检查型异常: • 编译期间编译器不对其进行检查的异常,包括Error类和RuntimeException类及其子类。 • 检查型异常: • 除非检查型异常以外的其它异常。 • 编译时,编译器对方法进行分析,如方法中有产生这种异常的可能,那么方法中要么有异常的处理模块,要么必须在方法头部抛出异常,否则,不能通过编译。 那么,Exception是检查型还是非检查型异常?ArithmeticException呢?
自定义异常 • 自定义异常也是一个类,如果我们要创建检查型的 异常,我们可以继承Exception类;如果我们要创建非检查型的异常,我们可以继承RuntimeException类
如何创建自定义异常 • 打开MyMath.java文件,假设我们在devide方法中不允许有负的除数,当接收到一个负的除数时,程序返回一个自定义的异常,通知调用者。 • 首先创建一个异常类DevideByMinusException • class DevideByMinusException extends Exception{ //定义子类构造器方法 public DevideByMinusException(String msg){ super(msg); } • }
抛出自定义异常 声明devide方法将抛出两种类型的异常 class MyMath{ public int devide(int x,int y) throws ArithmeticException,DevideByMinusException{ if(y<0) throw new DevideByMinusException("除数为负数"); int result=x/y; return result; } } Java通过throw关键字抛出异常对象。注意throws和throw的区别
throw关键字 • 用throw语句可以创建并抛出明确的异常 • 语法形式: • Throw new xxException();如: try { if(flag<0) { throw new NullPointerException(); } }……
调用者需做的修改 • class MyMathTest{ • public static void main(String[] args){ • try{ • MyMath mobj; • mobj=new MyMath(); • int result; • result=mobj.devide(3,0); • // result=mobj.devide(3,-1); • System.out.println("the result is " + result); • }catch(ArithmeticException e){ • System.out.println("程序发生ArithmeticException"); • } • catch(DevideByMinusException e){ • System.out.println("程序发生DevideByMinusException"); • } • catch(Exception e){ • System.out.println("程序发生其他类型异常"); • } • } • } 调用devide(3,0)方法,将跳转至该代码块运行 调用devide(3,-1)方法,将跳转至该代码块运行 发生其他异常,将跳转至该代码块运行
多catch结构 • 上面的程序,我们使用一个try后面跟着多个catch来捕捉异常,每一个catch可以处理一个不同的异常。 • 如果将catch(Exception e)代码块放到前面,行吗?为什么? • Exception类是所有异常类的父类,从语法上讲,是能够处理所有异常的。所以他后面的catch代码块永远都得不到执行 • 使用多catch结构捕获多种异常时,catch子句应该按先子类异常再父类异常的顺序排列
作业 • 作业:习题9,10