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

目录

  • 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


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

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

时间: 2024-10-03 03:29:26

Java 序列化和反序列化(三)Serializable 源码分析 - 2的相关文章

Java 序列化和反序列化(二)Serializable 源码分析 - 1

目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 Java 序列化和反序列化(二)Serializable 源码分析 - 1 在上一篇文章中讲解了一下 Serializable 的大致用法,本节重点关注 Java 序列化的实现,围绕 ObjectOutputStream#writeObject 方法展开. 1. Java 序列化接口 Java 为了方便开发人员将 Java 对象进行序列化及反序列化提供了一套方便的 API 来支持.其中包

EasyUI学习总结(三)——easyloader源码分析

EasyUI学习总结(三)--easyloader源码分析 easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依赖关系,先加载依赖项.模块加载好了会调用parse模块来解析页面.把class是easyui开头的标签都转化成easyui的控件. 先看Demo1例子,再分析源代码. 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>easyloader范例</tit

Java入门系列之集合HashMap源码分析(十四)

前言 我们知道在Java 8中对于HashMap引入了红黑树从而提高操作性能,由于在上一节我们已经通过图解方式分析了红黑树原理,所以在接下来我们将更多精力投入到解析原理而不是算法本身,HashMap在Java中是使用比较频繁的键值对数据类型,所以我们非常有必要详细去分析背后的具体实现原理,无论是C#还是Java原理解析,从不打算一行行代码解释,我认为最重要的是设计思路,重要的地方可能会多啰嗦两句. HashMap原理分析 我们由浅入深,循序渐进,首先了解下在HashMap中定义的几个属性,稍后会

java并发锁ReentrantReadWriteLock读写锁源码分析

1.ReentrantReadWriterLock基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为 如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读锁(锁降级):如果一个线程对资源加了读锁,其他线程可以继续加读锁. java.util.concurrent.locks中关于多写锁的接口:ReadWriteLock public interface ReadWriteLock { /** * Returns the lock used for r

2.Java集合-ConcurrentHashMap实现原理及源码分析

一.为何用ConcurrentHashMap 在并发编程中使用HashMap可能会导致死循环,而使用线程安全的HashTable效率又低下. 线程不安全的HashMap 在多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap 效率低下的HashTable Hashtable使用synchronized来保证线程的安全,但是在线程竞争激烈的情况下Hashtable的效率非常低下.当一个线程访问Hashtable的同步方法,

Java入门系列之集合Hashtable源码分析(十一)

前言 上一节我们实现了散列算法并对冲突解决我们使用了开放地址法和链地址法两种方式,本节我们来详细分析源码,看看源码中对于冲突是使用的哪一种方式以及对比我们所实现的,有哪些可以进行改造的地方. Hashtable源码分析 我们通过在控制台中实例化Hashtable并添加键值对实例代码来分析背后究竟做了哪些操作,如下: public static void main(String[] args) { Hashtable hashtable = new Hashtable(); hashtable.p

JAVA随笔篇一(Timer源码分析和scheduleAtFixedRate的使用)

写完了基础篇,想了很久要不要去写进阶篇,去写JSP等等的使用方法,最后决定先不去写,因为自己并不是JAVA方面的大牛,目前也在边做边学,所以决定先将自己不懂的拿出来学并记下来. Timer是Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务.这种方式可以让程序按照某一个频度执行. 1.Timer类的源码分析: public class Timer { /** * The timer task queue. This data structure

EasyUI学习总结(三)——easyloader源码分析(转载)

声明:这一篇文章是转载过来的,转载地址忘记了,原作者如果看到了,希望能够告知一声,我好加上去! easyloader模块是用来加载jquery easyui的js和css文件的,而且它可以分析模块的依赖关系,先加载依赖项.模块加载好了会调用parse模块来解析页面.把class是easyui开头的标签都转化成easyui的控件. 先看Demo1例子,再分析源代码. 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>ea

1.Java集合-HashMap实现原理及源码分析

哈希表(Hash  Table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出现在各类的面试题中,这里对java集合框架中的对应实现HashMap的实现原理进行讲解,然后对JDK7的HashMap的源码进行分析 哈希算法,是一类算法: 哈希表(Hash  Table)是一种数据结构: 哈希函数:是支撑哈希表的一类函数: HashMap 是 Java中用哈希数据结构实现的Ma