java核心学习(十七) IO框架---对象序列化

Posted The_shy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java核心学习(十七) IO框架---对象序列化相关的知识,希望对你有一定的参考价值。

一、使用对象流实现序列化。

  先定义一个可序列化的对象

    

package com.shy.IO;

import java.io.Serializable;

public class Person implements Serializable{
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int age;
    private String name;
    public Person(String name , int age){
        this.age = age;
        this.name = name;
    }
}

  然后将Persen类的实例使用对象流序列化


package com.shy.IO;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class WriteObject {
    public static void main(String[] args) {
        try (
                ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("object.txt"));
        ) {
            Person person = new Person("yuyu", 22);
            outputStream.writeObject(person);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }


    }
}
 

  最后再反序列化

package com.shy.IO;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ReadObject {
    public static void main(String[] args) {
        try (
                ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("object.txt"))
        ) {
            Person person = (Person) inputStream.readObject();
            System.out.println(person.getName()+"的年龄为"+person.getAge());
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {

        }
    }
}
 

  由上面代码可以看出,反序列化时必须进行downcasting,而且反序列化机制度区的仅仅是java对象的数据,而且没有使用对象构造器,这表明反序列化机制无需通过构造起来初始化java对象。

 

二、java对象序列化算法内容简介

  1、所有保存到磁盘中的对象都有一个序列化编号。

  2、当程序试图序列化一个对象时,程序会先检查该对象是否被序列化过,只有该对象从未(在本次虚拟机中)被序列化过,系统才会将对象转化为字节序列并输出。

  3、如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是再次重新序列化该对象。

 

三、自定义序列化

  对实现了Serializable接口的对象,可使用下列三种方式来自定义序列化与反序列化。

  第一种方式,若在实例成员变量前面使用transient关键字修饰,可以指定java序列化时无需理会该实例变量;

  第二种方式,在需要序列化的类中提供如下特殊签名的方法,在这些方法中分别对java对象的成员变量用out.writeObject()方法进行存取

  

private void writeObject(java.io.ObjectOutputStream out)throws IOException;
    private void readObject(java.io.ObjectInputStream in)throws IOException,ClassNotFoundException;
    private void readObjectNoData()throws ObjectStreamException;

  第三种方式,在序列化时将该对象替换成其他对象,此时应该为序列化提供如下方法,序列化机制会序列化该方法返回的对象。

    private Object writeReplace() throws ObjectStreamException;

  通过上面介绍,可以知道java序列化机制在将对象序列化写入文件之前,先调用被序列化对象的writeObject方法,然后再调用writeReplace方法,相对应的,在从文件中读取对象时的最后,会调用readObject方法,之后再调用readResolve方法,该方法和writeReplace方法很像,可以将源序列化对象转换为另一个对象来返回,可以用来实现白虎幸福之整个对象。

四、另一种序列化机制,实现Externalizable接口

  与serializable这种声明式接口不同,Externalizable接口里面定义了两个方法writeExternal() and readExternal()两个方法,这两个方法除了名字与writeObject和readObject不同外其他都相同,用处就是强制自定义序列化。

五、序列化的范围

  对象的类名和实例变量都会被序列化,方法、类变量,transient变量都不会被序列化。

六、serialVersionUID

  在定义序列化对象时最好手动定义序列化对象的版本,也就是在序列化对象中定义一个静态成员变量,private static fianl long serialVersionUID = 512L;用于保证class文件改变之后还可以正确反序列化。

以上是关于java核心学习(十七) IO框架---对象序列化的主要内容,如果未能解决你的问题,请参考以下文章

Java核心类库-IO-对象流(实现序列化与反序列化)

JAVA学习第四十七课 — IO流:文件的读写

java核心学习(十八) javaNIO框架---“块”模型的IO

Java 学习笔记 - IO篇:对象流 ObjectInputStreamObjectOutputStream

Java 学习笔记 - IO篇:对象流 ObjectInputStreamObjectOutputStream

Java IO学习总结