Java 序列化和反序列化(三)Serializable 源码分析 - 2

2020-12-06 23:04

阅读:611

标签:end   偏移量   数据信息   序列   tty   字段   ati   sha   throw   

目录

  • Java 序列化和反序列化(三)Serializable 源码分析 - 2
    • 1. ObjectStreamField
      • 1.1 数据结构
      • 1.2 构造函数
    • 2. ObjectStreamClass

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

参考:

  1. 《ObjectStreamClass源码分析》:https://blog.csdn.net/silentbalanceyh/article/details/8250096

每天用心记录一点点。内容也许不重要,但习惯很重要!

Java 序列化和反序列化(三)Serializable 源码分析 - 2

标签:end   偏移量   数据信息   序列   tty   字段   ati   sha   throw   

原文地址:https://www.cnblogs.com/binarylei/p/10989372.html


评论


亲,登录后才可以留言!