《8 异常(例外)处理与垃圾回收》由会员分享,可在线阅读,更多相关《8 异常(例外)处理与垃圾回收(36页珍藏版)》请在金锄头文库上搜索。
1、第八章异常(例外)处理与垃圾回收 课程目标课程目标Java的异常处理机制 try-catch机制 finally处理 throw与throws抛出异常 Java的垃圾回收机制什么是异常 在程序执行中,任何中断正常程序流程的异常条 件就是错误或异常。 表达式的计算违反了Java 语言的语义,例如整数 被0 除。 在载入或链接Java 程序时出错。 超出了某些资源限制,例如使用了太多的内存。 Java 程序代码中的throw 语句被执行。 异步异常发生。异步异常的原因可能有: Thread 的stop 方法被调用。 Java 虚拟机内部错误发生。异常处理机制 在用传统的语言编程时,程序员只能通过方
2、法的 返回值来发出错误信息,这容易导致很多错误。 C语言程序,为了处理“异常”情况,也常利用goto 语句。 Java对“异常”的处理是面向对象的。Java的 Exception是一个描述“异常”情况的对象。 当出现“异常”情况时,一个Exception对象就产生 了,并放到产生这个“异常”的成员方法里。 异常情况分类 异常分为运行时异常和一般异常。在Java语言中,通常所 说的异常是指程序运行过程中可能出现的非正常状态,即 虚拟机的通常操作中可能遇到的异常,是一种常见的运行 错误。 在Java语言中,“异常”可以看作是一个类,异常类的根是 Throwable。 Throwable是类库jav
3、a.lang包中的一个类,并派生出 Exception类和Error类两个子类。Exception类表示一种设 计或实现问题,换句话说,若程序正常运行,不会出现此 类异常。 Error类表示恢复不是不可能,但很困难的情况下的一种严 重异常,如内存溢出,程序自身不可能处理此类异常。 异常处理的5个控制关键字: try、catch、finally、throw和throws 想象一下异常发生:交 通事故异常处理程 序:警察try与catch try语句用大括号指定了一段代码,该段代码可 能会抛弃一个或多个异常。 catch语句的参数类似于方法的声明,包括一个异 常类型和一个异常对象。 catch语句
4、可以有多个,分别处理不同类的异常。 Java运行时系统从上到下分别对每个catch语句处 理的例外类型进行检测,直到找到类型相匹配的 catch语句为止。 也可以用一个catch语句处理多个异常类型,这时 它的异常类型参数应该是这多个异常类型的父类 ,程序设计中要根据具体的情况来选择catch语句 的异常处理类型。 异常的作用 Java程序在运行的过程中,尽管系统能提供默认的异常处 理程序,但通常喜欢自己处理异常。因为自己处理异常: 第一:能够对错误进行修正; 第二:能够防止程序自动终止。 try模块和catch模块是配套工作的,不能单独有try模块而 没有catch模块(有时try模块可由f
5、inally模块代替);同样 也不能没有try模块而直接出现catch模块。 正常执行流程的代码放在try模块中,当程序出现异常时, 抛出一个“异常事件”的信息,同时java Runtime接受此“异 常事件”并找出相应的catch模块来处理。Trycatch语法 try 正常执行流程的代码; catch(异常类型 变量) 异常对象变量的处理; Trycatch 流程图示异常类的继承结构 ThrowableErrorExceptionObjectAWTExceptionRuntimeExceptionIOException一个简单的trycatch示例 1.class Arithmetic 2
6、. 3.public static void main(String arg ) 4. 5.int a,b,c; 6.try 7. 8.a=10; 9.b=0; 10.c=a/b; 11.System.out.println(“正确执行到“); 12. 13.catch(ArithmeticException e) 14. 15.System.out.println(“分母不能为零n“+e.toString(); 16. 17. 18. 注意:程序出现异常时能从try模块转到catch模块中,一 旦出现异常将执行catch模块永远不会返回到try模块。 finally finally 是jav
7、a异常处理提供的另一个关键字,通 俗的说finally是异常处理语句结构的一部分,表示 无论什么情况都要执行的模块。 finally语句的主要作用是在try或catch转到其他部 分前做的一些“善后”工作。比如:关闭打开的文 件,释放链接、内存等系统资源。 finally语句的执行是一种无条件的操作,无论在哪 种异常下都会执行,即使try或catch模块中有 continue、return、break等关键字,或者是有 throw语句,程序都会执行finally 语句。 throw 关键字 throw总是出现在方法体中,用来抛出一个异常。 程序会在throw语句后立即终止,它后面的语句执 行不
8、到,然后在包含它的所有try块中(可能在上 层调用方法中),从里向外寻找含有与其匹配的 catch子句的try块。 下面是一个创建并引发异常的程序,与异常匹配 的处理程序再把它引发给外层的处理程序。 示例1.public class ThrowDemo 2.static void demoproc() 3.try 4.throw new NullPointerException(“demo“); 5. 6.catch(NullPointerException e) 7.System.out.println(“Caught inside demoproc.“); 8.throw e; 9. 10
9、. 11.public static void main(String args ) 12.try 13.demoproc(); 14. catch(NullPointerException e) 15.System.out.println(“Recaught: “ + e); 16. 17. 18. throws关键字 如果一个方法可以导致一个异常但不处理它,它必须指定这种行为以 使方法的调用者可以保护它们自己而不发生异常。 要做到这点可以在方法声明中包含一个throws子句。throws总是出现 在一个方法头中,用来标明该成员方法可能抛出的各种异常。 对大多数Exception子类来说,J
10、ava 编译器会强迫你声明在一个成员 方法中抛出的异常的类型。 一个throws 子句列举了一个方法可能引发的所有异常类型。这对于除 Error或RuntimeException及它们子类以外类型的所有异常是必要的。 一个方法可以引发的所有其他类型的异常必须在throws子句中声明。 如果不这样做,将会导致编译错误。 下面是包含一个throws子句的方法声明的通用形式:type method-name(parameter-list) throws exception-list / body of method exception-list是该方法可以引发的异常列表,中间以逗号分隔。 正确处理异
11、常 组合使用throws、try和throw 我们可以通过两种方式来恰当的处理异常: 1.使用try-catch-finally块来处理异常。 2.使用throws子句声明代码能引起的异常。 异常处理的思想是:尝试(try)执行一段代码,捕获( catch)所有可能抛处的异常,最后做一些清理工作。格 式如下: 1.try 2./可能会引起的异常的程序段 3.catch(ExceptionType e) 4./处理异常的程序段 5.finally 6./最后要做的清理工作 7.catch可以有多个catch()块,每一个都指定自己的 ExceptionType,它们的顺序为: 从想捕获的特定异常
12、到想捕获的异常的超类。 试图首先捕获超类的异常会导致编译时出错,比如,把带 有Exception类型的catch块放在带有IOException类型的 catch块前面就会导致编译时出错。 这种程序的执行结果会有以下两种情况: 1. 执行完所有try中的内容,没有跳到任何一个catch中去 。 2. 执行try的过程中产生某一种异常,然后跳到其中一个 catch块中。 不管是哪一种情况,最后都会去执行finally块中的内 容,这就是finally指令的用途。 异常的类型下面是一些经常可以见到的异常。 1. ArithmeticException:在出现不合法的数学运算时发生,比如 :除数为0
13、。 2. ArrayIndexOutOfBoundsException:如果使用非法的索引值访 问数组,就会抛出该异常。该异常说明索引要么是负值,要么大 于或者等于该数组的大小。 3. ClassNotFoundException:说明某类被调用,但是没有找到相 应的类文件,该类名或者不正确,或者该类对程序无效。 4. FileNotFoundException:访问一个文件时,必须准备处理该异 常,这是因为创建了某File并不意味着该文件存在。 5. IOException:在读写文件时发生错误的信号,在使用流的方法 时常常会遇到该异常。 6. NullPointerException:调用
14、使用null对象引用的方法,会见到 该异常。 7. NumberFormatException:将字符串转换为数字的时候,应该 处理该异常,以防该字符串实际上不能代表为数字。 8. StringIndexOutOfBoundsException:该异常试图在字符串边 界外进行索引。垃圾回收 当对象被创建时,就会在Java虚拟机的堆 区中拥有一块内存 在Java虚拟机的生命周期中,Java程序会 陆续地创建无数个对象 假如所有的对象都永久占有内存,那么内 存有可能很快被消耗光,最后引发内存空 间不足的错误。垃圾回收的优点Java语言中,内存回收的任务由Java虚拟机来担 当,而不是由Java程序
15、来负责。在程序的运行时 环境中,Java虚拟机提供了一个系统级的垃圾回 收器线程,它负责自动回收那些无用对象所占用 的内存,这种内存回收的过程被称为垃圾回收( Garbage Collection)。 垃圾回收具有以下优点: 1. 把程序员从复杂的内存追踪、监测和释放等工作中解 放出来,减轻程序员进行内存管理的负担。 2. 防止系统内存被非法释放,从而使系统更加健壮和稳 定。 垃圾回收的特点 1.只有当对象不再被程序中的任何引用变量引用时 ,它的内存才可能被回收。 2.程序无法迫使垃圾回收器立即执行垃圾回收操作 。 3.当垃圾回收器将要回收无用对象的内存时,先调 用该对象的finalize()
16、方法,该方法有可能使对象复 活,导致垃圾回收器取消回收该对象的内存。 透视Java垃圾回收 Java的堆是一个运行时数据区,类的实例(对象)从中分 配空间。 Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建 立的所有对象,这些对象通过new、newarray、 anewarray和multianewarray等指令建立,但是它们不需 要程序代码来显式地释放。 在命令行中有一个参数-verbosegc 可以查看Java使用的 堆内存的情况,它的格式如下: java -verbosegc classfile示例1.class TestGc 2. 3. public static void main