Java 序列化和反序列化Serializable 源码分析 - 2
Posted binarylei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 序列化和反序列化Serializable 源码分析 - 2相关的知识,希望对你有一定的参考价值。
目录
Java 序列化和反序列化(三)Serializable 源码分析 - 2
在上一篇文章中围绕 ObjectOutputStream#writeObject 讲解了一下序列化的整个流程,这中间很多地方涉及到了 ObjectStreamClass 和 ObjectStreamField 这两个类。
ObjectStreamField
是字段的序列化描述符,包括字段名、字段值等。可以通过 ObjectStreamClass#getFields 获取所有需要序列化的字段信息。ObjectStreamClass
类的序列化描述符,包含类描述信息,字段的描述信息和 serialVersionUID。可以使用 lookup 方法找到/创建在此 Java VM 中加载的具体类的 ObjectStreamClass。
1. ObjectStreamField
ObjectStreamField 只是一个简单的 JavaBean,保存了序列化过程中字段的元数据信息,包括字段的类型、类型代码、签名等。 可以通过 ObjectStreamClass#getFields 获取所有需要序列化的字段信息。
1.1 数据结构
private final String name; // 1. field name
private final String signature; // 2. canonical JVM signature of field type
private final Class<?> type; // 3. 字段类型
private final boolean unshared; // 4. 序列化时字段是否是 unshared
private final Field field; // 5. Field
private int offset = 0; // 6. 序列化时数据在 buffer 中的偏移量
offer
在序列化的过程中,当一个对象的成员属性个数超过一个时,JVM 会将会把所有的成员属性打包成一个“组”来操作,而 offset 就是这个组中当前描述的成员属性的偏移量,上层的 ObjectStreamClass 在调用当前这个成员属性的时候就使用偏移量进行引用定位操作;signature
该属性描述了 JVM 中成员属性的类型签名
JavaType | TypeCode |
---|---|
byte | B |
short | S |
int | I |
long | J |
float | F |
double | D |
char | C |
boolean | Z |
class | L |
arrary | [ |
1.2 构造函数
public ObjectStreamField(String name, Class<?> type, boolean unshared)
this.name = name;
this.type = type;
this.unshared = unshared;
signature = getClassSignature(type).intern();
field = null;
unshared 在 ObjectOutputStream源码分析的writeObject和writeUnshared区别进行了简单的说明,这里重点说一下 signature 这个属性。
具体的方法如下:
// JVM 中类型签名
private static String getClassSignature(Class<?> cl)
StringBuilder sbuf = new StringBuilder();
while (cl.isArray())
sbuf.append('[');
cl = cl.getComponentType();
if (cl.isPrimitive())
if (cl == Integer.TYPE)
sbuf.append('I');
else if (cl == Byte.TYPE)
sbuf.append('B');
else if (cl == Long.TYPE)
sbuf.append('J');
else if (cl == Float.TYPE)
sbuf.append('F');
else if (cl == Double.TYPE)
sbuf.append('D');
else if (cl == Short.TYPE)
sbuf.append('S');
else if (cl == Character.TYPE)
sbuf.append('C');
else if (cl == Boolean.TYPE)
sbuf.append('Z');
else if (cl == Void.TYPE)
sbuf.append('V');
else
throw new InternalError();
else
sbuf.append('L' + cl.getName().replace('.', '/') + ';');
return sbuf.toString();
2. ObjectStreamClass
参考:
- 《ObjectStreamClass源码分析》:https://blog.csdn.net/silentbalanceyh/article/details/8250096
每天用心记录一点点。内容也许不重要,但习惯很重要!
以上是关于Java 序列化和反序列化Serializable 源码分析 - 2的主要内容,如果未能解决你的问题,请参考以下文章
Java序列化和反序列化为什么要实现Serializable接口
Java序列化和反序列化为什么要实现Serializable接口
Java 序列化和反序列化,为什么要实现 Serializable 接口?
面试官问:Java 序列化和反序列化为什么要实现 Serializable 接口?什么鬼??