JAVA 中级- JAVA 对象流 OBJECTINPUTSTREAM,OBJECTOUTPUTSTREAM

1.JAVA 对象流

        Java IO 对象流

        对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘。

        一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口。

[疯狂Java]I/O:I/O流的最高境界——对象流(序列化:手动序列化、自动序列化、引用序列化、版本)

1. 什么是对象流:序列化/反序列化的概念

    1) 对象流是和字节流/字符流同处于一个概念体系的:

        a. 这么说字节流是流动的字节序列,字符流是流动的字符序列,那么对象流就是流动的对象序列咯?

        b. 概念上确实可以这样理解,对象流就是专门用来传输Java对象的;

        c. 但是字节和字符都是非常直观的二进制码(字节本身就是,而字符是一种二进制编码),二进制码的流动是符合计算机的概念模型的,可是对象是一个抽象的东西,对象怎么能像二进制码那样流动呢?

        d. 其实很好理解,对象流只不过是Java的API而已,表象上(方法调用等)流动的是对象,而实际上在底层肯定都是转换成二进制码流动的;

        e. 具体来说底层是将对象转换成平台无关的Java字节流进行传播的,以为对象流的类名就是ObjectInputStream和ObjectOutputStream,以stream作为后缀必然传递的是字节流;

        f. 只不过在调用对象流的read和write系列方法时不用将对象转换成字节数组传入了,而是可以直接传入对象本身,这些方法内部会自动将对象转化成字节流传递!!

java 对象流_对象流的理解

数据流操作的是我们的基本数据类型和字符串,对象流除了基本数据类型和字符串还包括我们其它的各种对象(也包括我们自定义的对象),所以对象流是数据流的升级版。同时这个流有个特殊的叫法叫做序列化和反序列化,不是所有的对象都可以序列化(必须要有通行证),必须实现Serializable接口。
 

2.序列化

java序列化,看这篇就够了

  • 序列化:将对象写入到IO流中
  • 反序列化:从IO流中恢复对象
  • 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
  • 使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。

序列化

        序列化是指把一个Java对象变成二进制内容,本质上就是一个byte[]数组。

        为什么要把Java对象序列化呢?因为序列化后可以把byte[]保存到文件中,或者把byte[]通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了。

        有序列化,就有反序列化,即把一个二进制内容(也就是byte[]数组)变回Java对象。有了反序列化,保存到文件中的byte[]数组又可以“变回”Java对象,或者从网络上读取byte[]并把它“变回”Java对象。

 

java序列化与反序列化全讲解

为什么需要序列化与反序列化

         我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

         当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

3.如何序列化

        注:把一个对象序列化有一个前提是:这个对象的类,必须实现了Serializable接口

一个Java对象要能序列化,必须实现一个特殊的java.io.Serializable接口,它的定义如下:

public interface Serializable {
}

Serializable接口没有定义任何方法,它是一个空接口。我们把这样的空接口称为“标记接口”(Marker Interface),实现了标记接口的类仅仅是给自身贴了个“标记”,并没有增加任何方法。

public class TestStream {
    
    public static void main(String[] args) {
        //创建一个Hero garen
        //要把Hero对象直接保存在文件上,务必让Hero类实现Serializable接口
        Hero h = new Hero();
        h.name = "garen";
        h.hp = 616;
          
        //准备一个文件用于保存该对象
        File f =new File("d:/garen.lol");
 
        try(
            //创建对象输出流
            FileOutputStream fos = new FileOutputStream(f);
            ObjectOutputStream oos =new ObjectOutputStream(fos);
            //创建对象输入流              
            FileInputStream fis = new FileInputStream(f);
            ObjectInputStream ois =new ObjectInputStream(fis);
        ) {
            oos.writeObject(h);
            Hero h2 = (Hero) ois.readObject();
            System.out.println(h2.name);
            System.out.println(h2.hp);
               
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            
    }
}

上一篇:2021-04-10 263. 丑数


下一篇:[问题]org.mybatis.generator.exception.XMLParserException: XML Parser Error on line 18: 对实体 "chara