




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JAVA教程 第四讲 Java的例外处理和I/O流41 什么是例外例外就是在程序的运行过程中所发生的异常事件,它中断指令的正常执行。Java中提供了一种独特的处理例外的机制,通过例外来处理程序设计中出现的错误。411 例外示例【例4-1】 import Java.io.*; class ExceptionDemo1public static void main( String args )FileInputStream fis = new FileInputStream( text );int b;while( (b=fis.read()!=-1 )System.out.print( b );fis.close( );查看编译结果【例4-2】 class ExceptionDemo2public static void main( String args )int a = 0;System.out.println( 5/a ); 运行结果C:javac ExceptionDemo2.JavaC:Java ExceptionDemo2Java.lang.ArithmeticException: / by zero atExceptionDemo2.main(ExceptionDemo2.Java:4) 因为除数不能为0,所以在程序运行的时候出现了除0溢出的异常事件。为什么有的例外在编译时出现,而有的例外是在运行时出现的?让我们继续学习Java 的例外处理机制。412 例外处理机制抛弃(throw)例外:在Java程序的执行过程中,如果出现了异常事件,就会生成一个例外对象。生成的例外对象将传递给Java运行时系统,这一例外的产生和提交过程称为抛弃(throw)例外两种处理例外的机制: 捕获例外:当Java运行时系统得到一个例外对象时,它将会沿着方法的调用栈逐层回溯,寻找处理这一例外的代码。找到能够处理这种类型的例外的方法后,运行时系统把当前例外对象交给这个方法进行处理,这一过程称为捕获(catch)例外。这是积极的例外处理机制。如果Java运行时系统找不到可以捕获例外的方法,则运行时系统将终止,相应的Java程序也将退出。 声明抛弃例外:如果一个方法并不知道如何处理所出现的例外,则可在方法声明时,声明抛弃(throws)例外。这是一种消极的例外处理机制。413 例外类的层次在jdk中,每个包中都定义了例外类,而所有的例外类都直接或间接地继承于Throwable类。图4-1为jdk中例外类的继承关系。Java中的例外类可分为两大类:Error动态链接失败,虚拟机错误等,通常Java程序不应该捕获这类例外,也不会抛弃这种例外。Exception1)运行时例外: 继承于RuntimeException的类都属于运行时例外,例如算术例外(除零错)、数组下标越界例外等等。由于这些例外产生的位置是未知的,Java 编译器允许程序员在程序中不对它们做出处理。 2)非运行时例外: 除了运行时例外之外的其他由Exception 继承来的例外类都是非运行时的例外,例如FileNotFoundException(文件未找到例外)。Java编译器要求在程序中必须处理这种例外,捕获例外或者声明抛弃例外。42 例外的处理Java语言中有两种例外处理机制:捕获例外和声明抛弃例外。下面我们做详细介绍。421 捕获例外捕获例外是通过try-catch-finally语句实现的。try.catch( ExceptionName1 e ).catch( ExceptionName2 e ).finally. try捕获例外的第一步是用try选定捕获例外的范围,由try所限定的代码块中的语句在执行过程中可能会生成例外对象并抛弃。 catch每个try代码块可以伴随一个或多个catch语句,用于处理try代码块中所生成的例外事件。catch语句只需要一个形式参数指明它所能够捕获的例外类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛弃的例外对象传递给catch块。在catch块中是对例外对象进行处理的代码,与访问其它对象一样,可以访问一个例外对象的变量或调用它的方法。getMessage( )是类Throwable所提供的方法,用来得到有关异常事件的信息,类Throwable还提供了方法printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。例如:try.catch( FileNotFoundException e )System.out.println( e );System.out.println( message: +e.getMessage() );e.printStackTrace( System.out );catch( IOException e )System.out.println( e );catch 语句的顺序:捕获例外的顺序和catch语句的顺序有关,当捕获到一个例外时,剩下的catch语句就不再进行匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的例外,然后再逐渐一般化。也就是一般先安排子类,再安排父类。 finally捕获例外的最后一步是通过finally语句为例外处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。422 声明抛弃例外1声明抛弃例外如果在一个方法中生成了一个例外,但是这一方法并不确切地知道该如何对这一异常事件进行处理,这时,一个方法就应该声明抛弃例外,使得例外对象可以从调用栈向后传播,直到有合适的方法捕获它为止。声明抛弃例外是在一个方法声明中的throws子句中指明的。例如:public int read () throws IOException.throws子句中同时可以指明多个例外,之间由逗号隔开。例如: public static void main(String args) throws IOException,IndexOutOfBoundsException 2抛出例外抛出例外就是产生例外对象的过程,首先要生成例外对象,例外或者由虚拟机生成,或者由某些类的实例生成,也可以在程序中生成。在方法中,抛出例外对象是通过throw语句实现的。例如:IOException e=new IOException();throw e ;可以抛出的例外必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:throw new String(want to throw);43 自定义例外类的使用自定义例外类必须是Throwable的直接或间接子类。注意:一个方法所声明抛弃的例外是作为这个方法与外界交互的一部分而存在的。所以,方法的调用者必须了解这些例外,并确定如何正确的处理他们。44 I/O 流概述输入/输出处理是程序设计中非常重要的一部分,比如从键盘读取数据、从文件中读取数据或向文件中写数据等等。Java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。Jdk 提供了包java.io,其中包括一系列的类来实现输入/输出处理。下面我们对Java.io包的内容进行概要的介绍。441 I/O流的层次 1字节流:从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。 InputStream、OutputStream FileInputStream、FileOutputStream PipedInputStream、PipedOutputStream ByteArrayInputStream、ByteArrayOutputStream FilterInputStream、FilterOutputStream DataInputStream、DataOutputStream BufferedInputStream、BufferedOutputStream2字符流:从Reader和Writer派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。 Reader、Writer InputStreamReader、OutputStreamWriter FileReader、FileWriter CharArrayReader、CharArrayWriter PipedReader、PipedWriter FilterReader、FilterWriter BufferedReader、BufferedWriter StringReader、StringWriter3对象流 ObjectInputStream、ObjectOutputStream4其它 文件处理:File、RandomACCESSFile; 接口DataInput、DataOutput、ObjectInput、ObjectOutput;442 InputStream 和OutputStream1InputStream 从流中读取数据:int read( ); /读取一个字节,返回值为所读的字节int read( byte b ); /读取多个字节,放置到字节数组b中,通常 /读取的字节数量为b的长度,返回值为实际 /读取的字节的数量int read( byte b , int off, int len ); /读取len个字节,放置 /到以下标off开始字节 /数组b中,返回值为实 /际读取的字节的数量int available( ); /返回值为流中尚未读取的字节的数量long skip( long n ); /读指针跳过n个字节不读,返回值为实际/跳过的字节数量 关闭流:close( ); /流操作完毕后必须关闭 使用输入流中的标记:void mark( int readlimit ); /记录当前读指针所在位置,readlimit /表示读指针读出readlimit个字节后/所标记的指针位置才失效void reset( ); /把读指针重新指向用mark方法所记录的位置boolean markSupported( );/当前的流是否支持读指针的记录功能有关每个方法的使用,详见Java API。2OutputStream 输出数据:void write( int b ); /往流中写一个字节bvoid write( byte b ); /往流中写一个字节数组bvoid write( byte b , int off, int len ); /把字节数组b中从/下标off开始,长度为len的字节写入流中 flush( ) /刷空输出流,并输出所有被缓存的字节由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。 关闭流: close( ); /流操作完毕后必须关闭443 I/O中的例外进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。如:FileNotFoundException, EOFException, IOException45 文件处理I/O处理中,最常见的是对文件的操作,Java.io包中有关文件处理的类有:File、FileInputStream、FileOutputStream、RamdomACCESSFile和FileDescriptor;接口有:FilenameFilter。 451 文件描述类File提供了一种与机器无关的方式来描述一个文件对象的属性。下面我们介绍类File中提供的各种方法。 文件或目录的生成public File(String path);/*如果path是实际存在的路径,则该File对象/*表示的是目录;如果path是文件名,则该File对象表示的是文件。*/public File(String path,String name);/path是路径名,name是文件名public File(File dir,String name);/dir是路径名,name是文件名 文件名的处理String getName( ); /得到一个文件的名称(不包括路径)String getPath( ); /得到一个文件的路径名String getAbsolutePath( );/得到一个文件的绝对路径名String getParent( ); /得到一个文件的上一级目录名String renameTo(File newName); /将当前文件名更名为给定文件的 完整路径 文件属性测试boolean exists( ); /测试当前File对象所指示的文件是否存在boolean canWrite( );/测试当前文件是否可写boolean canRead( );/测试当前文件是否可读boolean isFile( ); /测试当前文件是否是文件(不是目录)boolean isDirectory( ); /测试当前文件是否是目录 普通文件信息和工具long lastModified( );/得到文件最近一次修改的时间long length( ); /得到文件的长度,以字节为单位boolean delete( ); /删除当前文件 目录操作boolean mkdir( ); /根据当前对象生成一个由该对象指定的路径String list( ); /列出当前目录下的文件【例4-3】import Java.io.*; /引入Java.io包中所有的类public class FileFilterTestpublic static void main(String args)File dir=new File(d:/ex); /用File 对象表示一个目录Filter filter=new Filter(Java); /生成一个名为Java的过滤器System.out.println(list Java files in directory +dir);String files=dir.list(filter); /列出目录dir下,文件后缀名 为Java的所有文件for(int i=0;iJava NumberInput123Input value is 123Input value changed after doubled: 246注意:在读取字符流时,如果不是来自于本地的,比如说来自于网络上某处的与本地编码方式不同的机器,那么我们在构造输入流时就不能简单地使用本地缺省的编码方式,否则读出的字符就不正确;为了正确地读出异种机上的字符,我们应该使用下述方式构造输入流对象:ir = new InputStreamReader(is, 8859_1);采用ISO 8859_1编码方式,这是一种映射到ASCII码的编码方式,可以在不同平台之间正确转换字符。48 对象的串行化(Serialization)481 串行化的定义 1 什么是串行化对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)。 2 串行化的目的串行化的目的是为Java的运行环境提供一组特性,其主要任务是写出对象实例变量的数值。482 串行化方法在Java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化。1 定义一个可串行化对象public class Student implements Serializableint id; /学号String name; /姓名int age; /年龄String department /系别public Student(int id,String name,int age,String department)this.id = id; = name;this.age = age;this.department = department;2 构造对象的输入/输出流要串行化一个对象,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复。Java.io包中,提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象。在ObjectInputStream中用readObject()方法可以直接读取一个对象,ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。Student stu=new Student(981036,Liu Ming,18, CSD);FileOutputStream fo=new FileOutputStream(data.ser);/保存对象的状态ObjectOutputStream so=new ObjectOutputStream(fo);tryso.writeObject(stu);so.close(); catch(IOException e )System.out.println(e);FileInputStream fi=new FileInputStream(data.ser);ObjectInputStream si=new ObjectInputStream(fi);/恢复对象的状态trystu=(Student)si.readObject();si.close(); catch(IOException e )System.out.println(e);在这个例子中,我们首先定义一个类Student,实现了 Serializable接口,然后通过对象输出流的writeObject()方法将Student对象保存到文件data.ser中。之后,通过对象输入流的readObject()方法从文件data.ser中读出保存下来的Student对象。 483 串行化的注意事项1串行化能保存的元素只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。2transient关键字对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或一个FileInputStream对象,对于这些字段,我们必须用transient关键字标明3 定制串行化缺省的串行化机制,对象串行化首先写入类数据和类字段的信息,然后按照名称的上升排列顺序写入其数值。如果想自己明确地控制这些数值的写入顺序和写入种类,必须定义自己的读取数据流的方式。就是在类的定义中重写writeObject()和readObject()方法。例如可在4.8.2的例子中,加入重写的writeObject()和readObject()方法,对Student 类定制其串行化。private void writeObject(ObjectOutputStream out)throws IOExceptionout.writeInt(id);out.writeInt(age);out.writeUTF(name);out.writeUTF(department);private void readObject(ObjectInputStream in)throws IOExceptionid=in.readInt();age=in.readInt();name=in.readUTF();department=in.readUTF();49 其它常用的流491 管道流管道用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入 。管道输入流作为一个通信管道的接收端,管道输出流作为发送端。在使用管道之前,管道输出流和管道输入流必须进行连接。下面有两种连接的方法:1 构造方法中连接PipedInputStream(PipedO
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 能源行业智能监控与调度管理方案
- 旅游行业智慧旅游营销与品牌推广方案
- 专升本考前冲刺练习题附答案详解(预热题)
- 二年级数学计算题专项练习
- 中考数学总复习《 圆》综合提升测试卷及参考答案详解【预热题】
- 老年教育课程设置与教学方法创新聚焦2025年老年科技素养提升报告
- 自考专业(汉语言文学)题库检测试题打印及参考答案详解【预热题】
- 自考专业(会计)常考点试卷及完整答案详解(必刷)
- 风能行业智能化风力发电站建设与运营方案
- 电竞公司出口管理规定
- 七年级班主任开学第一课课件
- XXX有限公司报销审核制度
- WS/T 427-2013临床营养风险筛查
- GA/T 1047-2013道路交通信息监测记录设备设置规范
- GJB9001C内审员培训讲学课件
- 五牌一图(完整版)
- 幼儿园绘本故事:《十二生肖》 课件
- 激光跟踪仪使用手册
- 新媒体运营知识考核试题与答案
- 金属材料的主要性能ppt课件(完整版)
- 丽声北极星自然拼读绘本第二级 Fat Cat 课件
评论
0/150
提交评论