目录
- Java 序列化和反序列化(三)Serializable 源码分析 - 2
- 1. ObjectStreamField
- 1.1 数据结构
- 1.2 构造函数
- 2. ObjectStreamClass
- 1. ObjectStreamField
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
每天用心记录一点点。内容也许不重要,但习惯很重要!
原文地址:https://www.cnblogs.com/binarylei/p/10989372.html
时间: 2024-10-03 03:29:26