资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

java序列化

Java 更新时间: 发布时间: 计算机考试归档 最新发布

java序列化

什么是java序列化与反序列化
  • 序列化:把java对象通过某种方式写入磁盘,或者传输给其他网络节点。即将对象转为二进制的过程。
  • 反序列化:把磁盘中的文件,或者网络节点的数据通过某种方式转为java对象。即将二进制转为对象。
java序列化的使用场景

通过上面序列化的定义,可以初步了解序列化的使用场景。

  • 将内存中的数据保存到磁盘或者数据库中。
  • 需要在网络中传输对象。
  • 想通过RMI传输对象。
java序列化实例

下面直接上代码,通过代码实例学习如何实现序列化。

创建实体

为了深入理解实现序列化与反序列化,首先创建几个实体。
User.java、Person.java、OtherInfo.java,他们的关系是User.java中引用了OtherInfo.java,User.java继承了Person.java。三个实体都有get/set/toString方法,方便查看测试效果。

为何创建创建这三个实体呢?

  • 测试是否能序列化父类的数据
  • 测试是否能序列化引用类型的数据

代码如下:

User.java

package org.ludk.serializable;

import java.io.Serializable;


public class User extends Person  {
    private String name;
    private int age;
    private OtherInfo otherInfo;

    public User(String name, int age, OtherInfo otherInfo) {
        this.name = name;
        this.age = age;
        this.otherInfo = otherInfo;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", otherInfo=" + otherInfo +
                '}'+
                super.toString();
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public OtherInfo getOtherInfo() {
        return otherInfo;
    }

    public void setOtherInfo(OtherInfo otherInfo) {
        this.otherInfo = otherInfo;
    }
}

OtherInfo.java

package org.ludk.serializable;

import java.io.Serializable;


public class OtherInfo  {
    private String ph;
    private String address;

    public OtherInfo(String ph, String address) {
        this.ph = ph;
        this.address = address;
    }

    @Override
    public String toString() {
        return "OtherInfo{" +
                "ph='" + ph + ''' +
                ", address='" + address + ''' +
                '}';
    }

    public String getPh() {
        return ph;
    }

    public void setPh(String ph) {
        this.ph = ph;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Person.java

package org.ludk.serializable;

import java.io.Serializable;


public class Person  {
    private String head;
    private String body;

    @Override
    public String toString() {
        return "Person{" +
                "head='" + head + ''' +
                ", body='" + body + ''' +
                '}';
    }

    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

java序列化与反序列化工具类

SerializableUtil.java

package org.ludk.serializable;

import java.io.*;


public class SerializableUtil {
    
    public static void saveObject(Object object){
        ObjectOutputStream objectOutputStream=null;
        FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=new FileOutputStream("D:\work\test\serializable\writeToFile.txt");
            objectOutputStream=new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                objectOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static Object readObject(){
        ObjectInputStream objectInputStream=null;
        FileInputStream fileInputStream=null;
        try {
            fileInputStream=new FileInputStream("D:\work\test\serializable\writeToFile.txt");
            objectInputStream=new ObjectInputStream(fileInputStream);
            return objectInputStream.readObject();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                objectInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    } 
}

测试类

TestSerializable.java

package org.ludk.serializable;


public class TestSerializable {

    public static void main(String[] args) {
        User user=new User("卢**",35,new OtherInfo("1834156****","北京海淀"));
        user.setHead("大头");
        user.setBody("小身体");
        //打印序列化前的对象
        System.out.println(user);
        //序列化
        SerializableUtil.saveObject(user);
        //反序列化
        User readFromFile=(User) SerializableUtil.readObject();
        //打印通过反序列化生成的对象
        System.out.println(readFromFile);
    }
}

测试与修正的过程
  1. 运行TestSerializable.java的main方法,结果如下:
D:workjavabinjava.exe "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3libidea_rt.jar=51808:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3bin" -Dfile.encoding=UTF-8 -classpath D:workjavajrelibcharsets.jar;D:workjavajrelibdeploy.jar;D:workjavajrelibextaccess-bridge-64.jar;D:workjavajrelibextcldrdata.jar;D:workjavajrelibextdnsns.jar;D:workjavajrelibextjaccess.jar;D:workjavajrelibextjfxrt.jar;D:workjavajrelibextlocaledata.jar;D:workjavajrelibextnashorn.jar;D:workjavajrelibextsunec.jar;D:workjavajrelibextsunjce_provider.jar;D:workjavajrelibextsunmscapi.jar;D:workjavajrelibextsunpkcs11.jar;D:workjavajrelibextzipfs.jar;D:workjavajrelibjavaws.jar;D:workjavajrelibjce.jar;D:workjavajrelibjfr.jar;D:workjavajrelibjfxswt.jar;D:workjavajrelibjsse.jar;D:workjavajrelibmanagement-agent.jar;D:workjavajrelibplugin.jar;D:workjavajrelibresources.jar;D:workjavajrelibrt.jar;D:workspringcloud-demotargetclasses org.ludk.serializable.TestSerializable
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='大头', body='小身体'}
java.io.NotSerializableException: org.ludk.serializable.User
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at org.ludk.serializable.SerializableUtil.saveObject(SerializableUtil.java:27)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:17)
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.ludk.serializable.User
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1631)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at org.ludk.serializable.SerializableUtil.readObject(SerializableUtil.java:55)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:18)
Caused by: java.io.NotSerializableException: org.ludk.serializable.User
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at org.ludk.serializable.SerializableUtil.saveObject(SerializableUtil.java:27)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:17)
null

Process finished with exit code 0

java.io.NotSerializableException: org.ludk.serializable.User的意思很明显,org.ludk.serializable.User不能被实例化。

结论一:被序列化的对象实体需要实现java.io.Serializable接口,否则会抛NotSerializableException异常

所以让org.ludk.serializable.User实现serializable接口,被调整的部分代码如下:

public class User extends Person implements Serializable {

  1. 再次跑测试类,结果如下:
D:workjavabinjava.exe "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3libidea_rt.jar=52041:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3bin" -Dfile.encoding=UTF-8 -classpath D:workjavajrelibcharsets.jar;D:workjavajrelibdeploy.jar;D:workjavajrelibextaccess-bridge-64.jar;D:workjavajrelibextcldrdata.jar;D:workjavajrelibextdnsns.jar;D:workjavajrelibextjaccess.jar;D:workjavajrelibextjfxrt.jar;D:workjavajrelibextlocaledata.jar;D:workjavajrelibextnashorn.jar;D:workjavajrelibextsunec.jar;D:workjavajrelibextsunjce_provider.jar;D:workjavajrelibextsunmscapi.jar;D:workjavajrelibextsunpkcs11.jar;D:workjavajrelibextzipfs.jar;D:workjavajrelibjavaws.jar;D:workjavajrelibjce.jar;D:workjavajrelibjfr.jar;D:workjavajrelibjfxswt.jar;D:workjavajrelibjsse.jar;D:workjavajrelibmanagement-agent.jar;D:workjavajrelibplugin.jar;D:workjavajrelibresources.jar;D:workjavajrelibrt.jar;D:workspringcloud-demotargetclasses org.ludk.serializable.TestSerializable
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='大头', body='小身体'}
java.io.NotSerializableException: org.ludk.serializable.OtherInfo
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at org.ludk.serializable.SerializableUtil.saveObject(SerializableUtil.java:27)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:17)
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.ludk.serializable.OtherInfo
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1631)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2341)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2265)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2123)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1624)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at org.ludk.serializable.SerializableUtil.readObject(SerializableUtil.java:55)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:18)
Caused by: java.io.NotSerializableException: org.ludk.serializable.OtherInfo
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at org.ludk.serializable.SerializableUtil.saveObject(SerializableUtil.java:27)
	at org.ludk.serializable.TestSerializable.main(TestSerializable.java:17)
null

Process finished with exit code 0

java.io.NotSerializableException: org.ludk.serializable.OtherInfo
这段错误说明OtherInfo也要实现serializable接口。

结论二:引用对象的实体类也需要实现java.io.Serializable接口,否则抛NotSerializableException异常。

调整的部分代码如下:

public class OtherInfo  implements Serializable{

  1. 再次跑测试类,结果如下:
D:workjavabinjava.exe "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3libidea_rt.jar=52382:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3bin" -Dfile.encoding=UTF-8 -classpath D:workjavajrelibcharsets.jar;D:workjavajrelibdeploy.jar;D:workjavajrelibextaccess-bridge-64.jar;D:workjavajrelibextcldrdata.jar;D:workjavajrelibextdnsns.jar;D:workjavajrelibextjaccess.jar;D:workjavajrelibextjfxrt.jar;D:workjavajrelibextlocaledata.jar;D:workjavajrelibextnashorn.jar;D:workjavajrelibextsunec.jar;D:workjavajrelibextsunjce_provider.jar;D:workjavajrelibextsunmscapi.jar;D:workjavajrelibextsunpkcs11.jar;D:workjavajrelibextzipfs.jar;D:workjavajrelibjavaws.jar;D:workjavajrelibjce.jar;D:workjavajrelibjfr.jar;D:workjavajrelibjfxswt.jar;D:workjavajrelibjsse.jar;D:workjavajrelibmanagement-agent.jar;D:workjavajrelibplugin.jar;D:workjavajrelibresources.jar;D:workjavajrelibrt.jar;D:workspringcloud-demotargetclasses org.ludk.serializable.TestSerializable
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='大头', body='小身体'}
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='null', body='null'}

Process finished with exit code 0

这次不抛异常了,但是父类Person.java的属性没有被序列化,head和body为空。

结论三:父类也要实现java.io.Serializable接口,否则父类的属性不会被序列化。

调整的部分代码如下:

public class Person  implements Serializable{

  1. 再次跑测试类,结果如下:
D:workjavabinjava.exe "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3libidea_rt.jar=52500:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.3bin" -Dfile.encoding=UTF-8 -classpath D:workjavajrelibcharsets.jar;D:workjavajrelibdeploy.jar;D:workjavajrelibextaccess-bridge-64.jar;D:workjavajrelibextcldrdata.jar;D:workjavajrelibextdnsns.jar;D:workjavajrelibextjaccess.jar;D:workjavajrelibextjfxrt.jar;D:workjavajrelibextlocaledata.jar;D:workjavajrelibextnashorn.jar;D:workjavajrelibextsunec.jar;D:workjavajrelibextsunjce_provider.jar;D:workjavajrelibextsunmscapi.jar;D:workjavajrelibextsunpkcs11.jar;D:workjavajrelibextzipfs.jar;D:workjavajrelibjavaws.jar;D:workjavajrelibjce.jar;D:workjavajrelibjfr.jar;D:workjavajrelibjfxswt.jar;D:workjavajrelibjsse.jar;D:workjavajrelibmanagement-agent.jar;D:workjavajrelibplugin.jar;D:workjavajrelibresources.jar;D:workjavajrelibrt.jar;D:workspringcloud-demotargetclasses org.ludk.serializable.TestSerializable
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='大头', body='小身体'}
User{name='卢**', age=35, otherInfo=OtherInfo{ph='1834156****', address='北京海淀'}}Person{head='大头', body='小身体'}

Process finished with exit code 0

完美了。
听说静态变量不会被序列化( static,transient),我就不试了。
结论四:静态变量不会被序列化( static,transient)

序列化ID

序列化时一般会加入下面的代码(我没加):

 private static final long serialVersionUID = 1L;

它决定着是否能够成功反序列化!

java的序列化机制是通过判断运行时类的serialVersionUID来验证版本一致性的,在进行反序列化时,JVM会把传进来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。

因为我测试的时候是用一个实体序列化和反序列化,所以看不出效果。

java序列化总结
  • 被序列化的对象实体需要实现java.io.Serializable接口,否则会抛NotSerializableException异常。

  • 引用对象的实体类也需要实现java.io.Serializable接口,否则抛NotSerializableException异常

  • 父类也要实现java.io.Serializable接口,否则父类的属性不会被序列化。

  • 静态变量不会被序列化( static,transient)

  • 序列化ID应自己写,尽量不自动生成,因为序列化与反序列化的序列化ID应该保持一致

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/352013.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【java序列化】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2