Java 实现 序列化 与 反序列化

序列化 与 反序列化

序列化

Class ObjectOutputStream

java.lang.Object
java.io.OutputStream
java.io.ObjectOutputStream

实现接口

Closeable , DataOutput , Flushable , ObjectOutput , ObjectStreamConstants , AutoCloseable

可以通过使用流的文件来实现对象的持久存储
如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象(发个文件到另一台电脑实现对象)

注意:

  • 实现重构的对象必须实现 Java.io.Serializable 接口
  • 重构对象的属性也必须实现 Java.io.Serializable 接口

以上说明是实现重构对象的前提

构造方法

ObjectOutputStream()
ObjectOutputStream(OutputStream out)

方法 (方法自行API)

反序列化

Class ObjectInputStream

java.lang.Object
java.io.InputStream
java.io.ObjectInputStream

实现接口

Closeable , DataInput , ObjectInput , ObjectStreamConstants , AutoCloseable

ObjectInputStream用于恢复先前序列化的对象
构造方法

ObjectInputStream()
ObjectInputStream(InputStream in)

方法 (方法自行API)

序列化限制

指定对象部分属性序列化

实现方式:

  1. 对象属性用 transient 修饰符 限制属性序列化
  2. 对象属性用 static 修饰符 限制属性序列化
  3. 对象实现 writeObject()方法 和 readObject()方法 进行对指定属性进行实例化

注意:
方法3 ,writeObject()方法 和 readObject()方法 必须是 私有 无返回,否则无效

//模板
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//写
private void writeObject(ObjectOutputStream out) throws IOException
//读
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException

代码实例

Main类 (写入操作)

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        MySerializableUtil su = new MySerializableUtil();
        
        //数据处理 ,储存
        
        People p = new People("柏竹" , 20 , null);
        
        List<String> childrenName = new ArrayList<>();
        childrenName.add("黑猫");
        childrenName.add("大鲸");
        childrenName.add("白兔");
        HaveAll haveAll = new HaveAll(7654321 , "网球" , 3);
        haveAll.setChildrenName(childrenName);
        p.setHaveAll(haveAll);
    
        System.out.println("原始数据 : "+ p);
        
        //数据 序列化
        
        String fileName = "Date.txt";
        try {
    
    
            MySerializableUtil.mySerializableUtil(p , fileName);
            System.out.println("Serialization OK!");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    
        //读取
        System.out.println("读数据 : ");
        Object o = su.myDeserialize(fileName);
        System.out.println(o);
    }
}

/*

原始数据 : People{name='柏竹', age=20, haveAll=HaveAll{money=7654321, house='网球', childrenNum=3}}
 调用 writeObject() 限制!!!
Serialization OK!
读数据 : 
 调用 readObject() !!!
People{name='柏竹', age=20, haveAll=HaveAll{money=0, house='网球', childrenNum=3}}

*/

Input类 (读文件数据)(用于在别的地方读取对象)

public class Input {
    
    
    public static void main(String[] args) {
    
    
        MySerializableUtil su = new MySerializableUtil();
        Object o = su.myDeserialize("Date.txt");
        System.out.println(o);
    }
}

MySerializableUtil类 (操作工具)

import java.io.*;

/**
 * 序列化 与 序列化 工具类
 */
public class MySerializableUtil {
    
    
    /**
     * 序列化
     * @param data  数据
     * @param fileName  字节输出流
     */
    public static void mySerializableUtil(Object data , String fileName){
    
    
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
    
    
            oos.writeObject(data);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
    
    /**
     *  反序列化
     * @param fileName 字节输入流
     * @return 返回获取的对象
     */
    public static Object myDeserialize(String fileName){
    
    
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
    
    
            return ois.readObject();
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
        return null;
    }
}

People类 (存储对象)

import java.io.IOException;
import java.io.Serializable;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 * 实现Serializable接口
 */
public class People implements Serializable {
    
    
    String name;
    //年龄不能序列化
    static int age;
    /**人的明细*/
    HaveAll haveAll;
    
    //指定对象序列化
    private void writeObject(ObjectOutputStream out) throws IOException {
    
    
        System.out.println(" 调用 writeObject() 限制!!!");
        out.writeObject(name);
        out.writeObject(haveAll);
    }
    
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
    
    
        System.out.println(" 调用 readObject() !!!");
        name =(String) in.readObject();
        haveAll = (HaveAll) in.readObject();
    }
    
    public People() {
    
    
    }
    public People(String name , int age , HaveAll haveAll) {
    
    
        this.name = name;
        this.age = age;
        this.haveAll = haveAll;
    }
    
    public void setHaveAll(HaveAll haveAll) {
    
    
        this.haveAll = haveAll;
    }
    
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public void setAge(int age) {
    
    
        this.age = age;
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public int getAge() {
    
    
        return age;
    }
    
    public HaveAll getHaveAll() {
    
    
        return haveAll;
    }
    
    @Override
    public String toString() {
    
    
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", haveAll=" + haveAll +
                '}';
    }
}

HaveAll类 (存储PeoPle对象中的对象)

import java.io.Serializable;
import java.util.List;

public class HaveAll implements Serializable {
    
    
    // 余额 & 爱好 & 已有的孩子 & 孩子名字集合
    // 余额不能序列化对象
    private transient long money;
    String house;
    int childrenNum;
    List<String> childrenName;
    //不多写了
    
    public HaveAll() {
    
     }
    public HaveAll(long money , String house ,int childrenNum) {
    
    
        this.money = money;
        this.house = house;
        this.childrenNum = childrenNum;
    }
    
    public List<String> getChildrenName() {
    
    
        return childrenName;
    }
    
    public void setChildrenName(List<String> childrenName) {
    
    
        this.childrenName = childrenName;
    }
    
    public void setMoney(long money) {
    
    
        this.money = money;
    }
    
    public void setHouse(String house) {
    
    
        this.house = house;
    }
    
    public void setChildrenNum(int childrenNum) {
    
    
        this.childrenNum = childrenNum;
    }
    
    public long getMoney() {
    
    
        return money;
    }
    
    public String getHouse() {
    
    
        return house;
    }
    
    public int getChildrenNum() {
    
    
        return childrenNum;
    }
    
    @Override
    public String toString() {
    
    
        return "HaveAll{" +
                "money=" + money +
                ", house='" + house + '\'' +
                ", childrenNum=" + childrenNum +
                '}';
    }
}

Externalizable接口 序列化

继承接口
Serializable

实现类
ActivationDataFlavor , DataFlavor , MimeType , MLet , PrivateMLet

Externalizable接口 也能实现 序列化 和 反序列化 ,因继承 Serializable接口。
使用该接口需要定义 writeExteranl()readExternal() 抽象方法才可以实现序列化与反序列化

//模板
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//写
public void writeExternal(ObjectOutputStream out) throws IOException
//读
public void readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException

实现方式:
在以上代码中的 People类 更改

import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 * 实现Serializable接口
 */
public class People implements Externalizable {
    
    
    String name;
    //年龄不能序列化
    static int age;
    /**人的明细*/
    HaveAll haveAll;
    
    //指定对象序列化
 public void writeExternal(ObjectOutputStream out) throws IOException {
    
    
        System.out.println(" 调用 writeObject() 限制!!!");
        out.writeObject(name);
        out.writeObject(haveAll);
    }
    
public void readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException{
    
    
        System.out.println(" 调用 readObject() !!!");
        name =(String) in.readObject();
        haveAll = (HaveAll) in.readObject();
    }
    
   //·····省略
}

猜你喜欢

转载自blog.csdn.net/weixin_45963193/article/details/113900783