Java序列化机制原理,java面试题,java基础笔试题,BAT


写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家。扫码加微信好友进【程序员面试学习交流群】,免费领取。也欢迎各位一起在群里探讨技术。

Java序列化就是将一个对象转化为一个二进制表示的字节数组,通过保存或则转移这些二进制数组达到持久化的目的。要实现序列化,需要实现java.io.Serializable接口。反序列化是和序列化相反的过程,就是把二进制数组转化为对象的过程。在反序列化的时候,必须有原始类的模板才能将对象还原。从这个过程我们可以猜测到,序列化过程并不想class文件那样保存类的完整的结构信息。下面我们以一个简单的例子来看一下,序列化的时候都保存了哪些信息。代码如下:

package com.ysl;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class SerializableTest implements Serializable{

    private static final long serialVersionUID = -1L;

    public int num = 2018;

    public static void main(String[] args){

        try {

            FileOutputStream fos = new FileOutputStream("serializable");

            ObjectOutputStream oos = new ObjectOutputStream(fos);

            SerializableTest test = new SerializableTest();

            oos.writeObject(test);

            oos.flush();

            oos.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

序列化后的二进制字节数据如下:

aced 0005 7372 0018 636f 6d2e 7973 6c2e

5365 7269 616c 697a 6162 6c65 5465 7374

ffff ffff ffff ffff 0200 0149 0003 6e75

6d78 7000 0007 e2

上述的内容分为一下几个部分:

第一部分是序列化文件头




  •  
  • AC ED :STREAM_MAGIC声明使用了序列化协议


     
  • 00 05 :STREAM_VERSION序列化协议版本


     
  • 73 :TC_OBJECT声明这是一个新的对象


     

第二部分是序列化的类的描述,在这里是SerializableTest




  •  
  • 72 :TC_CLASSDESC声明这里开始一个新的class


     
  • 00 18:class名字的长度是24个字节


     
  • 636f 6d2e 7973 6c2e 5365 7269 616c 697a 6162 6c65 5465 7374:SerializableTest的完整类名


     
  • ffff ffff ffff ffff:serialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8字节的ID


     
  • 02 :标记号,声明该类支持序列化


     
  • 00 01:该类所包含的域的个数为1


     

第三部分是对象中各个属性的描述




  •  
  • 49:域类型,49代表I,也就是int类型


     
  • 00 03:域名字的长度为3


     
  • 6e 75 6d:num属性的名称


     

第四部分为对象的父类信息描述

SerializableTest没有父类,如果有,和第二部分的描述相同




  •  
  • 78 :TC_ENDBLOCKDATA,对象块的结束标志


     
  • 70:TC_NUL:说明没有其他超类的标志


     

第五部分为对象属性的实际值

如果属性是一个对象,那么这里还将序列化这个对象,规则和第二部分一样




  •  
  • 00 0007 e2:数值2018


     

虽然Java的序列化能够保证对象状态的持久保存,但是遇到一些对象结构复杂的情况还是比较难处理的,下面是对一些复杂情况的总结:




  •  
  • 当父类实现了Serializable接口的时候,所有的子类都能序列化


     
  • 子类实现了Serializable接口,父类没有,父类中的属性不能被序列化(不报错,但是数据会丢失)


     
  • 如果序列化的属性是对象,对象必须也能序列化,否则会报错


     
  • 反序列化的时候,如果对象的属性有修改或则删减,修改的部分属性会丢失,但是不会报错


     
  • 在反序列化的时候serialVersionUID被修改的话,会反序列化失败


     
  • 在存Java环境下使用Java的序列化机制会支持的很好,但是在多语言环境下需要考虑别的序列化机制,比如xml,json,或则protobuf


     


转载:https://www.cnblogs.com/senlinyang/p/8204752.html

推荐内容:
一个两年Java的面试总结
Java面试经
Java面试集合(七)
Java多线程面试题
深入理解Java中的反射机制
一、面试准备-Java知识
Java的深拷贝和浅拷贝
Java面试题——中级
java面试题目
Java面试通关要点汇总集

猜你喜欢

转载自blog.csdn.net/agoodcoder777/article/details/89438758
今日推荐