序列化和反序列化

本文深入探讨了序列化和反序列化的过程,详细解释了它们在存储和传输数据时的重要性。通过实例展示了如何在不同编程语言中实现序列化,并讨论了相关库和框架的应用。同时,还分析了序列化格式的优缺点,如JSON、XML和protobuf等。
摘要由CSDN通过智能技术生成
序列化过程:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,
            当反序列化时系统会去检测文件中的serialVersionUID,
            判断它是否与当前类的serialVersionUID一致,
            如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
serialVersionUID有两种显示的生成方式:        
一是默认的1L,比如:private static final long serialVersionUID = 1L;        
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:        
    private static final long  serialVersionUID = xxxxL;
    1 当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,
      Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,
      这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),
      就算再编译多次,serialVersionUID也不会变化的。
    2 如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,
      就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

当两次序列化的版本号serialVersionUID不一致时,会导致:   

[Java] 纯文本查看 复制代码

?

1

Exception in thread "main" java.io.InvalidClassException: com.demo.seriDemo.DataObject; local class incompatible: stream classdesc serialVersionUID = 1175939230834636559, local class serialVersionUID = -7343438723219659897




注意:
    (1)静态成员是不能被序列化的,因为静态成员是随着类的加载而加载的,与类共存亡,并且静态成员的默认初始值都是0;
     能被序列化的只是某个对象的成员.
    (2)如果同时在一次代码执行中进行序列化和反序列化,此时类中的静态成员是有值的,并不是因为静态的成员
     能够被序列化,而是此次运行jvm保存了静态成员。所以会发现好像静态成员被序列化和反序列化一样。
     
代码如下:
     

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

public static void main(String[] args) throws Exception {

        // 序列化DataObject对象

       Serialize();

        // 反序列DataObject对象

        DataObject object = Deserialize();

        // 静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已,

        // 这里的不能序列化的意思,是序列化信息中不包含这个静态成员域,下面

        // 之所以i输出还是2,是因为测试都在同一个机器(而且是同一个进程),因为这个jvm

        // 已经把i加载进来了,所以获取的是加载好的i,如果是传到另一台机器或者关掉程序重新

        // 写个程序读入DataObject.txt,此时因为别的机器或新的进程是重新加载i的,所以i信息就是初始时的信息,即0

        System.out.println(object);

    }

    /**

     * MethodName: SerializePerson

     * Description: 序列化对象

     * @author

     * @throws FileNotFoundException

     * @throws IOException

     */

    private static void Serialize() throws FileNotFoundException, IOException {

        DataObject object = new DataObject();

        object.setName("张三");

        object.setAge(10);

        // 创建ObjectOutputStream对象输出流,其中用到了文件的描述符对象和文件输出流对象

        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(

                new File("DataObject.txt")));

        // 将DataObject对象存储到DataObject.txt文件中,完成对DataObject对象的序列化操作

        oo.writeObject(object);

        System.out.println("对象序列化成功!");

        // 最后一定记得关闭对象描述符!!!

        oo.close();

    }

    /**

     * MethodName: DeserializePerson

     * Description: 反序列DataObject对象

     * @author

     * @return

     * @throws Exception

     * @throws IOException

     */

    private static DataObject Deserialize() throws Exception, IOException {

        // 创建ObjectInputStream对象输入流,其中用到了文件的描述符对象和文件输入流对象

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

                new File("DataObject.txt")));

        // 从DataObject.txt文件中读取DataObject对象,完成对DataObject对象的反序列化操作

        DataObject object = (DataObject) ois.readObject();

        System.out.println("对象反序列化成功!");

        // 最后一定记得关闭对象描述符!!!

        ois.close();

        return object;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值