精华内容
下载资源
问答
  • 萨特说过,人总说点什么,写点什么东西的欲望,我也不例外。不过,实践证明:不要相信CSDN的数据库,说不定天,你辛辛苦苦写的文字,找的资料,转瞬即逝。
    萨特说过,人总有说点什么,写点什么东西的欲望,我也不例外。不过,实践证明:不要相信CSDN的数据库,说不定哪天,你辛辛苦苦写的文字,找的资料,转瞬即逝。
    展开全文
  • Java的例外处理和I/O流

    2011-08-12 16:29:17
    原文:http://blog.csdn.net/coolriver/article/details/100692 【课前思考】  1. 什么例外?Java中有哪两种例外处理机制?  2. 字节流和字符流的基类各是什么?  3. 什么是对象的串行化?对象

    原文:http://blog.csdn.net/coolriver/article/details/100692


    【课前思考】
      1. 什么是例外?Java中有哪两种例外处理机制?
      2. 字节流和字符流的基类各是什么?
      3. 什么是对象的串行化?对象串行化的作用是什么?

    难点:
      1.如何使用Java中两种例外处理机制,抛弃例外和声明抛弃例外的区别与联系。
      2.处理字符流时,其构造方法的参数是一个字节流。
      3.对象串行化的概念。
    4.1 什么是例外

    4.1.2 例外处理机制

    抛弃(throw)例外
      在Java程序的执行过程中,如果出现了异常事件,就会生成一个例外对象。生成的例外对象将传递给Java运行时系统,这一例外的产生和提交过程称为抛弃(throw)例外。

    两种处理例外的机制:
      ◇捕获例外:
      当Java运行时系统得到一个例外对象时,它将会沿着方法的调用栈逐层回溯,寻找处理这一例外的代码。找到能够处理这种类型的例外的方法后,运行时系统把当前例外对象交给这个方法进行处理,这一过程称为捕获(catch)例外。这是积极的例外处理机制。如果Java运行时系统找不到可以捕获例外的方法,则运行时系统将终止,相应的Java程序也将退出。
      ◇声明抛弃例外:
      如果一个方法并不知道如何处理所出现的例外,则可在方法声明时,声明抛弃(throws)例外。这是一种消极的例外处理机制。

    4.1.3 例外类的层次
      在jdk中,每个包中都定义了例外类,而所有的例外类都直接或间接地继承于Throwable类。图4-1为jdk中例外类的继承关系。


    java中的例外类可分为两大类:
    Error
      动态链接失败,虚拟机错误等,通常Java程序不应该捕获这类例外,也不会抛弃这种例外。
    Exception
     1)运行时例外:
      继承于RuntimeException的类都属于运行时例外,例如算术例外(除零错)、数组下标越界例外等等。由于这些例外产生的位置是未知的,Java 编译器允许程序员在程序中不对它们做出处理。
     2)非运行时例外:
      除了运行时例外之外的其他由Exception 继承来的例外类都是非运行时的例外,例如FileNotFoundException(文件未找到例外)。Java编译器要求在程序中必须处理这种例外,捕获例外或者声明抛弃例外。

    4.2 例外的处理
    4.2.1 捕获例外
      
    捕获例外是通过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块中的语句都会被执行。

    4.2.2 声明抛弃例外

    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");

    4.3 自定义例外类的使用

    自定义例外类必须是Throwable的直接或间接子类。
      注意:一个方法所声明抛弃的例外是作为这个方法与外界交互的一部分而存在的。所以,方法的调用者必须了解这些例外,并确定如何正确的处理他们。

    4.4 I/O 流概述
    输入/输出处理是程序设计中非常重要的一部分,比如从键盘读取数据、从文件中读取数据或向文件中写数据等等。Java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。Jdk 提供了包java.io,其中包括一系列的类来实现输入/输出处理。下面我们对java.io包的内容进行概要的介绍。

    4.4.1 I/O流的层次
    1.字节流:
      从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。
      ◇ InputStream、OutputStream
      ◇ FileInputStream、FileOutputStream
      ◇ PipedInputStream、PipedOutputStream
      ◇ ByteArrayInputStream、ByteArrayOutputStream
      ◇ FilterInputStream、FilterOutputStream
      ◇ DataInputStream、DataOutputStream
      ◇ BufferedInputStream、BufferedOutputStream
     2.字符流:
      从Reader和Writer派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。
      ◇ Reader、Writer
      ◇ InputStreamReader、OutputStreamWriter
      ◇ FileReader、FileWriter
      ◇ CharArrayReader、CharArrayWriter
      ◇ PipedReader、PipedWriter
      ◇ FilterReader、FilterWriter
      ◇ BufferedReader、BufferedWriter
      ◇ StringReader、StringWriter
     3.对象流
      ◇ ObjectInputStream、ObjectOutputStream
     4.其它
      ◇ 文件处理:
      File、RandomAccessFile;
      ◇ 接口
      DataInput、DataOutput、ObjectInput、ObjectOutput;
    4.4.2 InputStream 和OutputStream

     1.InputStream
      ◇ 从流中读取数据:
      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( ); //当前的流是否支持读指针的记录功能
     2.OutputStream
      ◇ 输出数据:
      void write( int b );   //往流中写一个字节b
      void write( byte b[ ] ); //往流中写一个字节数组b
      void write( byte b[ ], int off, int len ); //把字节数组b中从
                  //下标off开始,长度为len的字节写入流中
      ◇ flush( )       //刷空输出流,并输出所有被缓存的字节
      由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
      ◇ 关闭流:
       close( );       //流操作完毕后必须关闭

    4.4.3 I/O中的例外

    进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。如:FileNotFoundException, EOFException, IOException。

    4.5 文件处理

    I/O处理中,最常见的是对文件的操作,java.io包中有关文件处理的类有:File、FileInputStream、FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。
    4.5.1 文件描述
      类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( ); //列出当前目录下的文件
    java的windows编程中,目录用如下形式:File dir = new File("e://myapp//src");
     

    4.5.2 文件的顺序处理
      类FileInputStream和FileOutputStream用来进行文件I/O处理,由它们所提供的方法可以打开本地主机上的文件,并进行顺序的读/写。例如,下列的语句段是顺序读取文件名为text的文件里的内容,并显示在控制台上面,直到文件结束为止。

    FileInputStream fis;
       try{
        fis = new FileInputStream( "text" );
       System.out.print( "content of text is : ");
         int b;
         while( (b=fis.read())!=-1 ) //顺序读取文件text里的内容并赋值
                        给整型变量b,直到文件结束为止。
         {              
           System.out.print( (char)b );
         }
       }catch( FileNotFoundException e ){
       System.out.println( e );
       }catch( IOException e ){
       System.out.println( e );
       }
    4.5.3 随机访问文件
      对于InputStream 和OutputStream 来说,它们的实例都是顺序访问流,也就是说,只能对文件进行顺序地读/写。随机访问文件则允许对文件内容进行随机读/写。在java中,类RandomAccessFile 提供了随机访问文件的方法。类RandomAccessFile的声明为:
    public class RandomAccessFile extends Object implements DataInput, DataOutput

    接口DataInput 中定义的方法主要包括从流中读取基本类型的数据、读取一行数据、或者读取指定长度的字节数。如:readBoolean( )、readInt( )、readLine( )、readFully( ) 等。
      接口DataOutput 中定义的方法主要是向流中写入基本类型的数据、或者写入一定长度的字节数组。如:writeChar( )、writeDouble( )、write( ) 等。 下面详细介绍RandomAccessFile类中的方法。
     ◇ 构造方法:
      RandomAccessFile(String name,String mode); //name是文件名,mode
              //是打开方式,例如"r"表示只读,"rw"表示可读写,"
      RandomAccessFile(File file,String mode); //file是文件对象
     ◇ 文件指针的操作
      long getFilePointer( ); //用于得到当前的文件指针
      void seek( long pos ); //用于移动文件指针到指定的位置
      int skipBytes( int n ); //使文件指针向前移动指定的n个字节

    4.6 过滤流

    过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。

    为了使用一个过滤流,必须首先把过滤流连接到某个输入/出流上,通常通过在构造方法的参数中指定所要连接的输入/出流来实现。例如:
      FilterInputStream( InputStream in );
      FilterOutputStream( OutputStream out );

    几种常见的过滤流:

      ◇ BufferedInputStream和BufferedOutputStream
        缓冲流,用于提高输入/输出处理的效率。
      ◇ DataInputStream 和 DataOutputStream
        不仅能读/写数据流,而且能读/写各种的java语言的基本类型,如:boolean,int,float等。
      ◇ LineNumberInputStream
        除了提供对输入处理的支持外,LineNumberInputStream可以记录当前的行号。
      ◇ PushbackInputStream
        提供了一个方法可以把刚读过的字节退回到输入流中,以便重新再读一遍。
      ◇ PrintStream
        打印流的作用是把Java语言的内构类型以其字符表示形式送到相应的输出流。

    4.7 字符流的处理

    java中提供了处理以16位的Unicode码表示的字符流的类,即以Reader和Writer 为基类派生出的一系列类。
    4.7.1 Reader和Writer

    这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成这两个类的实例,只能通过使用由它们派生出来的子类对象来处理字符流。
    1.Reader类是处理所有字符流输入类的父类。
      ◇ 读取字符

      public int read() throws IOException; //读取一个字符,返回值为读取的字符
      public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
      public abstract int read(char cbuf[],int off,int len) throws IOException;
      /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现(因为是抽象方法,否则类必须声明为抽象类)*/
      ◇ 标记流
      public boolean markSupported(); //判断当前流是否支持做标记
      public void mark(int readAheadLimit) throws IOException;
       //给当前流作标记,最多支持readAheadLimit个字符的回溯。
      public void reset() throws IOException; //将当前流重置到做标记处
      ◇ 关闭流
      public abstract void close() throws IOException;
     2. Writer类是处理所有字符流输出类的父类。
      ◇ 向输出流写入字符
      public void write(int c) throws IOException;
      //将整型值c的低16位写入输出流
      public void write(char cbuf[]) throws IOException;
      //将字符数组cbuf[]写入输出流
      public abstract void write(char cbuf[],int off,int len) throws IOException;
      //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
      public void write(String str) throws IOException;
      //将字符串str中的字符写入输出流
      public void write(String str,int off,int len) throws IOException;
      //将字符串str 中从索引off开始处的len个字符写入输出流
      ◇ flush( )
      刷空输出流,并输出所有被缓存的字节。
      ◇ 关闭流
      public abstract void close() throws IOException;

    4.7.2 InputStreamReader和OutputStreamWriter
      java.io包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介。

      ◇ 生成流对象
      public InputStreamReader(InputStream in);
      /*in是字节流,而InputStreamReader是字符流,但是其来源是字节流in,
      因此InputStreamReader就可以把字节流in转换成字符流处理。/*

      public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException;
      
    /*enc是编码方式,就是从字节流到字符流进行转换时所采用的编码方式,
       例如 ISO8859-1,UTF-8,UTF-16等等*/

      public OutputStreamWriter(OutputStream out);
      
    /*out是字节流,而OutputStreamReader是字符流 */
      public OutputStreamWriter(OutputStream out,String enc) throws UnsupportedEncodingException; //enc是编码方式
      InputStreamReader和OutputStreamWriter的方法:
      ◇ 读入和写出字符
      基本同Reader和Writer。
      ◇ 获取当前编码方式
      public String getEncoding();
      ◇ 关闭流
      public void close() throws IOException;

    4.7.3 BufferedReader和BufferedWriter

     ◇ 生成流对象
      public BufferedReader(Reader in); //使用缺省的缓冲区大小
      public BufferedReader(Reader in, int sz); //sz为缓冲区的大小
      public BufferedWriter(Writer out);
      public BufferedWriter(Writer out, int sz);
     ◇ 读入/写出字符
      除了Reader和Writer中提供的基本的读写方法外,增加对整行字符的处理。
      public String readLine() throws IOException; //读一行字符
      public void newLine() throws IOException; //写一行字符

     

    【例4-4】
          InputStreamReader ir;
          BufferedReader in;
          ir=new InputStreamReader(System.in);
          //从键盘接收了一个字符串的输入,并创建了一个字符输入流的对象,in的定//义如下:public static final InputStream in ,输出流out的定义如下:public static final //PrintStream out
          in=new BufferedReader(ir);
          String s=in.readLine();
          //从输入流in中读入一行,并将读取的值赋值给字符串变量s
          System.out.println("Input value is: "+s);
       注意:在读取字符流时,如果不是来自于本地的,比如说来自于网络上某处的与本地编码方式不同的机器,那么我们在构造输入流时就不能简单地使用本地缺省的编码方式,否则读出的字符就不正确;为了正确地读出异种机上的字符,我们应该使用下述方式构造输入流对象:
          ir = new InputStreamReader(is, "8859_1");
      采用ISO 8859_1编码方式,这是一种映射到ASCII码的编码方式,可以在不同平台之间正确转换字符。

     

    4.8 对象的串行化

    4.8.1 串行化的定义

     1. 什么是串行化
      对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)。

    2. 串行化的目的
      串行化的目的是为java的运行环境提供一组特性,其主要任务是写出对象实例变量的数值。

    4.8.2 串行化方法
      在java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化

     1. 定义一个可串行化对象
      public class Student implements Serializable{
        int id;
    //学号
        String name; //姓名
        int age; //年龄
        String department //系别
        public Student(int id,String name,int age,String department){
         this.id = id;
         this.name = 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);
      try{
        so.writeObject(stu);
        so.close();
        }catch(IOException e )
          {System.out.println(e);}
      FileInputStream fi=new FileInputStream("data.ser");
      ObjectInputStream si=new ObjectInputStream(fi);
      
    //恢复对象的状态
      try{
        stu=(Student)si.readObject();
        si.close();
        }catch(IOException e )
      {System.out.println(e);}
      
    在这个例子中,我们首先定义一个类Student,实现了 Serializable接口,然后通过对象输出流的writeObject()方法将Student对象保存到文件data.ser中。之后,通过对象输入流的readObject()方法从文件data.ser中读出保存下来的Student对象。

    4.8.3 串行化的注意事项

     1.串行化能保存的元素
      只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。
     2.transient关键字
      对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或一个FileInputStream对象,对于这些字段,我们必须用transient关键字标明,见3.2.1节
     3. 定制串行化
      缺省的串行化机制,对象串行化首先写入类数据和类字段的信息,然后按照名称的上升排列顺序写入其数值。如果想自己明确地控制这些数值的写入顺序和写入种类,必须定义自己的读取数据流的方式。就是在类的定义中重写接口serializeble的writeObject()和readObject()方法。
      例如可在4.8.2的例子中,加入重写的writeObject()和readObject()方法,对Student 类定制其串行化。
      private void writeObject(ObjectOutputStream out)throws IOException
      {
        out.writeInt(id);
        out.writeInt(age);
        out.writeUTF(name);
        out.writeUTF(department);
      }
      private void readObject(ObjectInputStream in)throws IOException
      {
        id=in.readInt();
        age=in.readInt();
        name=in.readUTF();
        department=in.readUTF();
      }

    4.9 其它常用的流

    4.9.1 管道流

    管道用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入。

    管道输入流作为一个通信管道的接收端,管道输出流作为发送端。在使用管道之前,管道输出流和管道输入流必须进行连接。下面有两种连接的方法:
     1. 构造方法中连接
      PipedInputStream(PipedOutputStream src);
      PipedOutputStream(PipedInputStream snk);
     2. connect()方法进行连接
      类PipedInputStream中定义为:
      void connect(PipedOutputStream src);
      类PipedOutputStream中定义为:
      void connect(PipedInputStream snk);

    4.9.2 内存的读/写

    1. ByteArrayInputStream和ByteArrayOutputStream
      ByteArrayInputStream //从字节数组中读取以字节为单位的数据
      ByteArrayOutputStream //向字节数组中写入以字节为单位的数据
    2. StringBufferInputStream和StringBufferOutputStream
      StringBufferInputStream
      //从字符串缓冲区StringBuffer中读取以字符为单位的数据
      StringBufferOutputStream
      //向字符串缓冲区StringBuffer中写入以字符为单位的数据

    4.9.3 顺序输入流

    SequenceInputStream 把几个输入流顺序连接起来。顺序输入流提供了把若干不同的流统一为同一个流的功能,使得程序变得更加简洁。
    展开全文
  • 牙科医生好像例外一些,字迹倒是工整,但常牙友好奇,字虽然认识,但上面的名词对我们来说一样是天书!比如,经常在医生的诊断本中出现的安氏分类是个什么东东。天灵灵地灵灵,且听牙套之家念个经,今天就教教...

    25a14b29bb8952e6f0fe8f933ae8c516.png

    传说,医生是最通神的职业。比如他们的处方经常是寻常人看不懂的天书。牙科医生好像例外一些,字迹倒是工整,但常有牙友好奇,字虽然认识,但上面有的名词对我们来说一样是天书!比如,经常在医生的诊断本中出现的安氏分类是个什么东东。

    b25166fe7eb5b5c08d70c0ddabd38a80.png

    天灵灵地灵灵,且听牙套之家念个经,今天就教教大家辨认牙科医生的天书的第一步——安氏分类是什么。

    要弄明白安氏分类是什么,首先得弄清安氏是谁。当当当,隆重向大家介绍这位重量级大咖——被誉为世界正畸之父、现代口腔正畸创始人的美国口腔医生——安格尔(Angle)!就是这位大牛医生在1899年提出了这种目前使用最为广泛的错畸形分类法——安氏分类法。这是目前国际上应用最广泛的一种错畸形分类方法。

    dea17b4aa4e82a03534897f5d3b7a563.png

    在了解安氏分类法之前,我们先来学习两个概念——“远中”和“近中”。

    这个“中”指的是中线,它是将我们颅面部平分为左右两等份的一条假想垂直线。中线通过左右两眼之间、鼻尖和左右两中切牙(就是我们常说的门牙)的接触区。对于口腔来说, 以上下中切牙为中点分开,牙齿靠近中线方向的就是近中,远离中线的方向就是远中。

    171e388cba758b969cf1cc53d88f2e57.png

    回到我们安大咖的理论上,他认为我们上颌骨的位置是恒定的,上颌骨的第一恒磨牙的位置更是恒定中的恒定,因此把这颗牙齿当作的关键,也就好比一个路标式“建筑”。

    0d21affca4c8c9512b644adb3f7ebb65.png

    安大咖认为,上颌骨位置既然是相对恒定的,那么,错畸形都是由下颌、下牙弓在近远中向的错位引起的。健康情况下,上颌第一恒磨牙的近中颊尖应该咬合于下颌第一恒磨牙的近中颊沟内,并且牙齿排列整齐无错位。他以上颌第一恒磨牙为参照将错畸形分为中性错(安氏Ⅰ类)、远中错(安氏Ⅱ类)、与近中错(安氏Ⅲ类)。

    0b992de50e8f382104c7ae9a2baf9e3b.png

    我们先来看中性错(安氏Ⅰ类)

    75f6467ac6d27b9f02acbb10f4a6619e.png

    这一类型上下牙弓的近、远中关系正常,即在正中颌位时,上颌第一恒磨牙的近中颊尖咬合于下颌第一恒磨牙的近中颊沟内,且牙列中存在错位牙,就是中性错,Angle将他归入Ⅰ类。

    5cdd6f9747b2289fd0ce212a26de73a8.png

    它可以表现为牙列拥挤、双牙弓前突、上牙弓前突、前牙深覆盖、前牙反,前牙深覆、后牙颊、舌向错位等。

    接着聊聊,远中错(安氏Ⅱ类)

    上下颌骨及牙弓的近、远中关系不调,下牙弓或下颌处于远中位置,磨牙为远中关系。通俗一点讲,就是我们将上颌第一恒磨牙为参考,相较于正常来说,下颌的第一恒磨牙向离牙齿中线远的那一方向缩了。

    253035c06a87bf278f5296057e7a9237.png

    这种磨牙为远中错的类型也可以分为两个小分类。

    第一分类,上颌切牙唇向倾斜,通俗讲就是前牙向外面倾斜。其中还有一个亚类,一侧磨牙为远中错关系,另一侧为中性关系,且上颌前牙唇向倾斜。

    这类错通常表现为:前牙深覆盖、深覆、牙列拥挤和开唇露齿等。

    ebe037a8d3eba000e9e540f26e3d82a6.png

    第二个分类,上颌切牙舌向倾斜。通俗讲就是前牙内扣。其中也有一个亚类,一侧磨牙为远中错关系,另一侧为正常牙关系,且上颌前牙向内倾斜。

    值得注意的是安氏二类二分类可能对美观影响不大,但对口腔健康的危害仍然存在,有需要也应该积极治疗哦。

    再来聊一聊近中错(安氏Ⅲ类)

    7ed497ca825332fef075ee578083dd3f.png

    这类错是指上下颌骨及牙弓的近远中关系不调,下颌及下牙弓处于近中位置,磨牙关系为近中关系。通俗点讲,就是我们将上颌第一恒磨牙为参考,相较于正常来说,下颌的第一恒磨牙向离牙齿中线近的那一方向突了。通常表现为:上颌正常,下颌前突;或者下颌正常, 上颌后缩;或者两者都有。这也包含一个亚类,磨牙关系一侧为近中,一侧为中性。

    197aba6d8bd91ec81d6742bc4a430e7a.png

    安氏分类法简单易懂,便于用于临床,但它其实并不完善,甚至有不少错漏之处,比如上颌第一恒磨牙的位置并非恒定不变的。对牙齿横向和垂直方向上的异常也没有涉及,另外牙量和骨量的不调,也未在分类中体现出来。

    b9a944e1cc15abec4e1e668902860618.png

    所以近百年来,国内外的学者们在不断更新新的分类方法,多达几十种,如我国毛燮钧教授的分类方法就非常有影响力哦。

    8531b5d6e036e3525dba11be410c77fe.png
    展开全文
  • Java中有哪两种例外处理机制? 2. 字节流和字符流的基类各是什么? 3. 什么是对象的串行化?对象串行化的作用是什么? 难点: 1.如何使用Java中两种例外处理机制,抛弃例外和声明抛弃例外的区别与联系。 2....

    【课前思考】
      1 什么是例外?Java中有哪两种例外处理机制?
      2 字节流和字符流的基类各是什么?
      3 什么是对象的串行化?对象串行化的作用是什么?

    难点:
      1.如何使用Java中两种例外处理机制,抛弃例外和声明抛弃例外的区别与联系。
      2.处理字符流时,其构造方法的参数是一个字节流。
      3.对象串行化的概念。
    4.1 什么是例外

    412 例外处理机制

    抛弃(throw)例外
      Java程序的执行过程中,如果出现了异常事件,就会生成一个例外对象。生成的例外对象将传递给Java运行时系统,这一例外的产生和提交过程称为抛弃(throw)例外。

    两种处理例外的机制:
       捕获例外:
      当Java运行时系统得到一个例外对象时,它将会沿着方法的调用栈逐层回溯,寻找处理这一例外的代码。找到能够处理这种类型的例外的方法后,运行时系统把当前例外对象交给这个方法进行处理,这一过程称为捕获(catch)例外。这是积极的例外处理机制。如果Java运行时系统找不到可以捕获例外的方法,则运行时系统将终止,相应的Java程序也将退出。
       声明抛弃例外:
      如果一个方法并不知道如何处理所出现的例外,则可在方法声明时,声明抛弃(throws)例外。这是一种消极的例外处理机制。

    413 例外类的层次
      在jdk中,每个包中都定义了例外类,而所有的例外类都直接或间接地继承于Throwable类。4-1jdk中例外类的继承关系。


    java
    中的例外类可分为两大类:

    Error
      动态链接失败,虚拟机错误等,通常Java程序不应该捕获这类例外,也不会抛弃这种例外。
    Exception
     1)运行时例外:
      继承于RuntimeException的类都属于运行时例外,例如算术例外(除零错)、数组下标越界例外等等。由于这些例外产生的位置是未知的,Java 编译器允许程序员在程序中不对它们做出处理。

     2)非运行时例外:

      除了运行时例外之外的其他由Exception 继承来的例外类都是非运行时的例外,例如FileNotFoundException(文件未找到例外)。Java编译器要求在程序中必须处理这种例外,捕获例外或者声明抛弃例外。

    4.2 例外的处理
    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");

    4.3 自定义例外类的使用

    自定义例外类必须是Throwable的直接或间接子类。
      注意:一个方法所声明抛弃的例外是作为这个方法与外界交互的一部分而存在的。所以,方法的调用者必须了解这些例外,并确定如何正确的处理他们。

    4.4 I/O 流概述
    输入/输出处理是程序设计中非常重要的一部分,比如从键盘读取数据、从文件中读取数据或向文件中写数据等等。Java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。Jdk 提供了包java.io,其中包括一系列的类来实现输入/输出处理。下面我们对java.io包的内容进行概要的介绍。

    441 I/O流的层次
    1.字节流:
      从InputStreamOutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。
       InputStreamOutputStream
       FileInputStream
    FileOutputStream
       PipedInputStream
    PipedOutputStream
       ByteArrayInputStream
    ByteArrayOutputStream
       FilterInputStream
    FilterOutputStream
       DataInputStream
    DataOutputStream
       BufferedInputStream
    BufferedOutputStream
     2.字符流:

      从ReaderWriter派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。
       ReaderWriter
       InputStreamReader
    OutputStreamWriter
       FileReader
    FileWriter
       CharArrayReader
    CharArrayWriter
       PipedReader
    PipedWriter
       FilterReader
    FilterWriter
       BufferedReader
    BufferedWriter
       StringReader
    StringWriter
     3.对象流

       ObjectInputStreamObjectOutputStream
     4.其它

       文件处理:
      FileRandomAccessFile
       接口
      DataInputDataOutputObjectInputObjectOutput
    442 InputStream OutputStream

     1InputStream
       从流中读取数据:
      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( ); //当前的流是否支持读指针的记录功能
     2OutputStream
       输出数据:
      void write( int b );   //往流中写一个字节b
      void write( byte b[ ] ); //往流中写一个字节数组b
      void write( byte b[ ], int off, int len ); //把字节数组b中从
                  //下标off开始,长度为len的字节写入流中
       flush( )       //刷空输出流,并输出所有被缓存的字节
      由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
       关闭流:
       close( );       //流操作完毕后必须关闭

    443 I/O中的例外

    进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。如:FileNotFoundException, EOFException, IOException

    4.5 文件处理

    I/O处理中,最常见的是对文件的操作,java.io包中有关文件处理的类有:FileFileInputStreamFileOutputStreamRamdomAccessFileFileDescriptor;接口有: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( );
    //列出当前目录下的文件
    java的windows编程中,目录用如下形式:File dir = new File("e://myapp//src");
     

    452 文件的顺序处理
      类FileInputStreamFileOutputStream用来进行文件I/O处理,由它们所提供的方法可以打开本地主机上的文件,并进行顺序的读/写。例如,下列的语句段是顺序读取文件名为text的文件里的内容,并显示在控制台上面,直到文件结束为止。

    FileInputStream fis;
      
    try{
        
    fis = new FileInputStream( "text" );
      
    System.out.print( "content of text is : ");
         
    int b;
         while( (b=fis.read())!=-1 ) //顺序读取文件text里的内容并赋值

                        给整型变量b,直到文件结束为止。
         {              

           System.out.print( (char)b );
         }
      
    }catch( FileNotFoundException e ){
      
    System.out.println( e );
      
    }catch( IOException e ){
      
    System.out.println( e );
       }

    453 随机访问文件
      对于InputStream OutputStream 来说,它们的实例都是顺序访问流,也就是说,只能对文件进行顺序地读/写。随机访问文件则允许对文件内容进行随机读/写。在java中,类RandomAccessFile 提供了随机访问文件的方法。类RandomAccessFile的声明为:
    public class RandomAccessFile extends Object implements DataInput, DataOutput

    接口DataInput 中定义的方法主要包括从流中读取基本类型的数据、读取一行数据、或者读取指定长度的字节数。如:readBoolean( )readInt( )readLine( )readFully( ) 等。
      接口DataOutput 中定义的方法主要是向流中写入基本类型的数据、或者写入一定长度的字节数组。如:writeChar( )writeDouble( )write( ) 等。 下面详细介绍RandomAccessFile类中的方法。

      构造方法:
      RandomAccessFile(String name,String mode); //name是文件名,mode
              //是打开方式,例如"r"表示只读,"rw"表示可读写,"

      RandomAccessFile(File file,String mode); //file是文件对象
      文件指针的操作
      long getFilePointer( ); //用于得到当前的文件指针
      void seek( long pos ); //用于移动文件指针到指定的位置
      int skipBytes( int n ); //使文件指针向前移动指定的n个字节

    4.6 过滤流

    过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。

    为了使用一个过滤流,必须首先把过滤流连接到某个输入/出流上,通常通过在构造方法的参数中指定所要连接的输入/出流来实现。例如:
      FilterInputStream( InputStream in );
      FilterOutputStream( OutputStream out );

    几种常见的过滤流:

      ◇ BufferedInputStream和BufferedOutputStream
        缓冲流,用于提高输入/输出处理的效率。
      ◇ DataInputStream 和 DataOutputStream
        不仅能读/写数据流,而且能读/写各种的java语言的基本类型,如:boolean,int,float等。
      ◇ LineNumberInputStream
        除了提供对输入处理的支持外,LineNumberInputStream可以记录当前的行号。
      ◇ PushbackInputStream
        提供了一个方法可以把刚读过的字节退回到输入流中,以便重新再读一遍。
      ◇ PrintStream
        打印流的作用是把Java语言的内构类型以其字符表示形式送到相应的输出流。

    4.7 字符流的处理

    java中提供了处理以16位的Unicode码表示的字符流的类,即以ReaderWriter 为基类派生出的一系列类。
    471 ReaderWriter

    这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成这两个类的实例,只能通过使用由它们派生出来的子类对象来处理字符流。
    1Reader类是处理所有字符流输入类的父类。
       读取字符

      public int read() throws IOException; //读取一个字符,返回值为读取的字符
      public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
      
    public abstract int read(char cbuf[],int off,int len) throws IOException;
      /*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现(因为是抽象方法,否则类必须声明为抽象类)
    */
       标记流

      public boolean markSupported(); //判断当前流是否支持做标记
      public void mark(int readAheadLimit) throws IOException;
       //给当前流作标记,最多支持readAheadLimit个字符的回溯。

      public void reset() throws IOException; //将当前流重置到做标记处
       关闭流
      public abstract void close() throws IOException;
     2 Writer类是处理所有字符流输出类的父类。

       向输出流写入字符
      public void write(int c) throws IOException
      //将整型值c的低16位写入输出流
      public void write(char cbuf[]) throws IOException
      //将字符数组cbuf[]写入输出流
      public abstract void write(char cbuf[],int off,int len) throws IOException
      //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
      public void write(String str) throws IOException
      //将字符串str中的字符写入输出流
      public void write(String str,int off,int len) throws IOException
      //将字符串str 中从索引off开始处的len个字符写入输出流
       flush( )
      刷空输出流,并输出所有被缓存的字节。
       关闭流
      public abstract void close() throws IOException

    472 InputStreamReaderOutputStreamWriter
      java.io包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介。

      ◇ 生成流对象
      public InputStreamReader(InputStream in);

      /*in是字节流,而InputStreamReader是字符流,但是其来源是字节流in,
      因此InputStreamReader就可以把字节流in转换成字符流处理。/*

      public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException;
      
    /*enc是编码方式,就是从字节流到字符流进行转换时所采用的编码方式,
       例如 ISO8859-1,UTF-8,UTF-16等等*/

      public OutputStreamWriter(OutputStream out);
      
    /*out是字节流,而OutputStreamReader是字符流 */
      public OutputStreamWriter(OutputStream out,String enc) throws UnsupportedEncodingException;
    //enc是编码方式
      InputStreamReader和OutputStreamWriter的方法:
      ◇ 读入和写出字符
      基本同Reader和Writer。
      ◇ 获取当前编码方式
      public String getEncoding();
      ◇ 关闭流
      public void close() throws IOException;

    4.7.3 BufferedReader和BufferedWriter

      生成流对象
      public BufferedReader(Reader in); //使用缺省的缓冲区大小
      public BufferedReader(Reader in, int sz); //sz为缓冲区的大小
      public BufferedWriter(Writer out);
      
    public BufferedWriter(Writer out, int sz);
      读入/写出字符

      除了ReaderWriter中提供的基本的读写方法外,增加对整行字符的处理。
      public String readLine() throws IOException; //读一行字符
      public void newLine() throws IOException; //写一行字符

     

    【例4-4
          InputStreamReader ir;
          
    BufferedReader in;
          
    ir=new InputStreamReader(System.in);
          //从键盘接收了一个字符串的输入,并创建了一个字符输入流的对象,in的定//义如下:public static final InputStream in ,输出流out的定义如下:
    public static final //PrintStream out
          in=new BufferedReader(ir);
          
    String s=in.readLine();
          //从输入流in中读入一行,并将读取的值赋值给字符串变量s

          System.out.println("Input value is: "+s);
       注意:在读取字符流时,如果不是来自于本地的,比如说来自于网络上某处的与本地编码方式不同的机器,那么我们在构造输入流时就不能简单地使用本地缺省的编码方式,否则读出的字符就不正确;为了正确地读出异种机上的字符,我们应该使用下述方式构造输入流对象:
          ir = new InputStreamReader(is, "8859_1");
      采用ISO 8859_1编码方式,这是一种映射到ASCII码的编码方式,可以在不同平台之间正确转换字符。

     

    4.8 对象的串行化

    4.8.1 串行化的定义

     1 什么是串行化
      对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)。
    对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)。

    2 串行化的目的
      串行化的目的是为java的运行环境提供一组特性,
    其主要任务是写出对象实例变量的数值

    482 串行化方法
      java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化

     1 定义一个可串行化对象
      public class Student implements Serializable{
        int id;
    //学号
        String name;
    //姓名
        int age;
    //年龄
        String department
    //系别
        public Student(int id,String name,int age,String department){
         this.id = id;
         this.name = 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);
      try{
        so.writeObject(stu);
        so.close();
        }catch(IOException e )
          {System.out.println(e);}
      FileInputStream fi=new FileInputStream("data.ser");
      ObjectInputStream si=new ObjectInputStream(fi);
      
    //恢复对象的状态
      try{
        stu=(Student)si.readObject();
        si.close();
        }catch(IOException e )
      {System.out.println(e);}
      
    在这个例子中,我们首先定义一个类Student,实现了 Serializable接口,然后通过对象输出流的writeObject()方法将Student对象保存到文件data.ser中。之后,通过对象输入流的readObject()方法从文件data.ser中读出保存下来的Student对象。

    4.8.3 串行化的注意事项

     1.串行化能保存的元素
      
    只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。
     
    2transient关键字
      对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或一个FileInputStream对象,对于这些字段,
    我们必须用transient关键字标明,见3.2.1节
     
    3 定制串行化
      缺省的串行化机制,对象串行化首先写入类数据和类字段的信息,然后按照名称的上升排列顺序写入其数值。如果想自己明确地控制这些数值的写入顺序和写入种类,必须定义自己的读取数据流的方式。就是在类的定义中重写接口serializeble的writeObject()和readObject()方法。
      例如可在4.8.2的例子中,加入重写的writeObject()和readObject()方法,对Student 类定制其串行化。
      private void writeObject(ObjectOutputStream out)throws IOException
      {
        out.writeInt(id);
        out.writeInt(age);
        out.writeUTF(name);
        out.writeUTF(department);
      }
      private void readObject(ObjectInputStream in)throws IOException
      {
        id=in.readInt();
        age=in.readInt();
        name=in.readUTF();
        department=in.readUTF();
      }

    4.9 其它常用的流

    4.9.1 管道流

    管道用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入。

    管道输入流作为一个通信管道的接收端,管道输出流作为发送端。在使用管道之前,管道输出流和管道输入流必须进行连接。下面有两种连接的方法:
     1 构造方法中连接
      PipedInputStream(PipedOutputStream src);
      
    PipedOutputStream(PipedInputStream snk);
     2 connect()方法进行连接

      PipedInputStream中定义为:
      void connect(PipedOutputStream src);
      类PipedOutputStream中定义为:

      void connect(PipedInputStream snk);

    4.9.2 内存的读/写

    1 ByteArrayInputStreamByteArrayOutputStream
      ByteArrayInputStream //从字节数组中读取以字节为单位的数据
      ByteArrayOutputStream //向字节数组中写入以字节为单位的数据
    2 StringBufferInputStreamStringBufferOutputStream
      StringBufferInputStream
      //从字符串缓冲区StringBuffer中读取以字符为单位的数据
      StringBufferOutputStream
      //向字符串缓冲区StringBuffer中写入以字符为单位的数据

    4.9.3 顺序输入流

    SequenceInputStream 把几个输入流顺序连接起来。顺序输入流提供了把若干不同的流统一为同一个流的功能,使得程序变得更加简洁。

    展开全文
  • 第四讲 Java的例外处理和I/O流

    千次阅读 2004-09-10 17:38:00
    Java中有哪两种例外处理机制? 2. 字节流和字符流的基类各是什么? 3. 什么是对象的串行化?对象串行化的作用是什么?难点: 1.如何使用Java中两种例外处理机制,抛弃例外和声明抛弃例外的区别与联系。 2....
  • 随着移动通讯的普及,手机成为现代生活中的必需品,但手机辐射的存在又让大家使用时...理论上讲,任何一种电器产品在运行过程中都会产生一定的辐射,蓝牙耳机也不例外,由于蓝牙耳机功率非常低,实际产生的辐射相对非
  • 先建表CREATE TABLE `menu_employee` (`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键,无实际意义',`employee_pid` int(5) DEFAULT NULL COMMENT '父节点序号,通常是部门的序号,可是已有例外,没有组的...
  • 什么叫带宽

    千次阅读 2016-03-17 22:41:53
    一、带宽的两种概念 如果从电子电路角度出发,带宽(Bandwidth)本意指的是电子电路中存在一个固有通频带,这个概念或许比较抽象,我们必要作进一步解释。大家都知道,各类复杂的电子电路无一例外都存在电感、...
  • 种寻线仪好用可靠

    2020-06-11 14:19:01
    没有遇到这种机房:打开像一碗拌好的面条一样,插上巡线仪,接近每一条线都在响,没法下手干活。网上寻线仪的品牌繁多,价格更是从100—3000不等,让人眼花缭乱,想要在这些品牌当中寻找到从质量到价格都过关的...
  • 或许以前,你会觉得不管是什么格式的文件,都可以用Windows自带的压缩工具来压缩,直到你发现视频文件是一个例外,PDF文件也是一个例外,没错,Windows自带的压缩工具虽然很强大,但是也不是万能的,也一些文件是...
  • 我能做什么

    2014-12-23 19:16:00
    少数人例外.大部分人会想想然后说,我好像没什么能量.不能做什么大的事情. 我的梦想在.毕了业这个问题就渐渐成为大部分人不再去想的问题.老男孩这首歌听的人越来越'老'就变得越来越催人泪下 终究个积累的过程....
  • 程序员的十个层次 你属于一层?

    万次阅读 多人点赞 2011-09-09 22:04:19
    一年前收藏的一篇文章,今早翻出来看看,突然很感悟,想和大家分享分享,究竟这条路可以走到什么程度,还是个未知数。 文章虽然有点长,兴趣的同学就仔细看看吧,对自己的发展还是好处的。   自西方文艺...
  • 自西方文艺复兴以来,中国在自然科学方面落后西方很多,...要解决这个问题,必须先知道程序员多少种技术层级,每个层级需要什么样的技术水平,然后再比较中国和西方在各个技术层级的人数,就可以知道到底没有
  • 自西方文艺复兴以来,中国在自然科学方面落后西方很多,...要解决这个问题,必须先知道程序员多少种技术层级,每个层级需要什么样的技术水平,然后再比较中国和西方在各个技术层级的人数,就可以知道到底没有
  • 不管在,不管从事什么职业,身份证都是必须随身携带品。所以,对于身份证上的数字我们也有着特殊的感情。众所周知,身份证号一般都是由十八个阿拉伯数字组成,但是一小部分人却例外。他们的最后一位并不是阿拉伯...
  • 这是源地址:http://www.huaxiapx.cn/html/2011/2/58.htm自西方文艺复兴以来,中国在自然科学方面落后西方很多,软件领域也不例外。...要解决这个问题,必须先知道程序员多少种技术层级,每个层级需要什么样的技
  • 少数人例外.大部分人会想想然后说,我好像没什么能量.不能做什么大的事情. 我的梦想在.毕了业这个问题就渐渐成为大部分人不再去想的问题.老男孩这首歌听的人越来越'老'就变得越来越催人泪下 终究个积累的过程....
  • 坐过飞机的朋友,相信都会过类似的疑问,我也不例外。旅行社、航空公司、网站报价各有千秋,难辩真假!随着经济条件越来越好,坐飞机的次数越来越多,总在这个问题上打转。我就想到可以找个比价的网站,最起码...
  • 如果从电子电路角度出发,带宽(Bandwidth)本意指的是电子电路中存在一个固有通频带,这个概念或许比较抽象,我们必要作进一步解释。大家都知道,各类复杂的电子电路无一例外都存在电感、电容或相当功能的储能...
  • 属于前一种的,十有八九这辈子就在监狱里呆着了(例外的也,诸如“收礼专收XXX”之类)。腐败贪污是一种骗,“全心全意为人民服务”的口号,估计每个贪污分子都拍着胸脯保证过;骗名利的似乎比骗钱的要斯文点,其实...
  • 两类用户例外,这就是具有sysdba或者sysoper权限的用户。Oracle sysdba或者sysoper用户的登陆两种方式:一是通过OS认证,二是通过密码文件验证。究竟使用一种验证方式以及能否成功登陆取决于三个方面的因素...
  • 一天八趟出入实验室,今儿个也不例外,下午来实验室没想到被门口保安大叔拦了... 大叔:(大手一拦)你去? 我:(懵逼..)实验室啊.. 大叔:(大声呵斥)? 我:(???什么鬼?)实验室! 大叔:啥? ...
  • 其实哪有什么互联网寒冬?只是你穿的少而已! 而想要成为一名优秀的Android开发,你需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~。 对于现在的Android及移动互联网来说,我们需要掌握的技.
  • 不管是一部动漫在现实中都会自己的取材背景,动漫里面的每一个角色都会由现实中的人或动物转变而成,当然洛洛历险记亦不例外。今天小编就和大家分享一下洛洛历险记中的机器人是从哪些动物或者其他的素材取材的:...
  • Java 程序员之路

    2018-06-01 18:02:40
    俗话说, 每个程序员心中都一个架构师的梦想,女程序员也不例外,我也不例外时候人难免都迷茫的时候,会不知道自己努力的方向是什么,要努力到什么时候才会实现我们的目标,理想?(就不传播负能量了...)...
  • noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大 部分的写入指令,但 DEL 和几个例外)allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据空间存放。volat...
  • 2011.9.21

    2011-09-21 20:48:54
    好像没有次写博文,是因为今天做成了什么事,或者因为什么事很开心,这次也不例外。 Libjpeg-turbo折腾了好几天,很奇怪地相对于Libjpeg没有任何加速比,甚至原来加速比的那次实验也无法重复出现结果,着实诡异...

空空如也

空空如也

1 2 3 4
收藏数 80
精华内容 32
关键字:

哪有什么例外