太阳集团2138备用网址

  • 监督曝光——中央纪委国家监委网站 2019-04-26
  • 人民日报现场评论:彰显新时代的开放决心 2019-04-26
  • 日本影片《小偷家族》和《未来的未来》获奥斯卡提名 2019-04-26
  • 《Super TV 2》首位挑战者AOA!“甜蜜厮杀”胜负预告 2019-04-26
  • 党建添马力,基层焕生机 2019-04-26
  • 多家赣新三板企业或将“离场” 2019-04-26
  • 扎克伯格有对手了!21岁的她获评史上最年轻白手起家亿万富翁 2019-04-26
  • 江苏开工建设城市“充电宝” 2019-04-26
  • 中国石油天然气集团有限公司曲广学接受纪律审查和监察调查中国石油天然气集团-要闻 2019-04-26
  • 「天眼网路电视台」 2018两岸媒体联访‧河南全真派圣地〔王屋山〕 2019-04-26
  • 携程第三季度净亏损1.65亿美元 同比转亏 2019-04-26
  • 防弹少年团金泰亨蓝发登各国热搜 玩儿转红粉金黑棕各种发色实力演绎“有颜任性”【组图】 2019-04-25
  • 龙烨为袁竹逍遥画派配画诗欣赏之三 2019-04-25
  • 因应增值税下调 多个豪车品牌在华降价 2019-04-25
  • “小屏论”话两会:“习语”暖人心 2019-04-25
  • 欢迎来到 黑吧太阳集团2138备用网址 是业内专业的游戏平台,为你提供各式各样的精品游戏,最全的游戏项目,同时还为您提供各种游戏专题游戏攻略人气论坛。

    浅析Java序列化和反序列化

    来源:本站整理 作者:佚名 时间:2019-01-15 TAG: 我要投稿

    太阳集团2138备用网址 www.r-island.com 序列化机制
    序列化 (Serialization) 是指将数据结构或对象状态转换成字节流 (例如存储成文件、内存缓冲,或经由网络传输) ,以留待后续在相同或另一台计算机环境中,能够恢复对象原来状态的过程。序列化机制在Java中有着广泛的应用,EJB、RMI、Hessian等技术都以此为基础。
    序列化
    我们先用一个简单的序列化示例来看看Java究竟是如何对一个对象进行序列化的:
    public class SerializationDemo implements Serializable {
        private String stringField;
        private int intField;
        public SerializationDemo(String s, int i) {
            this.stringField = s;
            this.intField = i;
        }
        public static void main(String[] args) throws IOException {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bout);
            out.writeObject(new SerializationDemo("gyyyy", 97777));
        }
    }
    如果熟悉PHP的同学应该知道,这个对象在经过PHP序列化后得到的字符串如下 (因为PHP与Java的编程习惯有所区别,这里字段访问权限全改为了public,private和protected从表现形式上来说差不多,只是多了些特殊的标识而已,为了减少一些零基础的同学不必要的疑惑,这里暂不讨论) :
    O:17:"SerializationDemo":2:{s:11:"stringField";s:5:"gyyyy";s:8:"intField";i:97777;}
    其中,O:17:"..."表示当前是一个对象,以及该对象类名的字符串长度和值,2:{...}表示该类有2个字段 (元素间用;分隔,键值对也分为前后两个元素表示,也就是说,如果是2个字段,则总共会包含4个元素) ,s:11:"..."表示当前是一个长度为11的字符串,i:...表示当前是一个整数。
    由此可知,PHP序列化字符串基本上是可人读的,而且对于类对象来说,字段等成员属性的序列化顺序与定义顺序一致。我们完全可以通过手工的方式来构造任意一个PHP对象的序列化字符串。
    而该对象经过Java序列化后得到的则是一个二进制串:
    ac ed 00 05 73 72 00 11  53 65 72 69 61 6c 69 7a    ....sr.. Serializ
    61 74 69 6f 6e 44 65 6d  6f d9 35 3c f7 d6 0a c6    ationDem o.502 00 02 49 00 08 69  6e 74 46 69 65 6c 64 4c    ....I..i ntFieldL
    00 0b 73 74 72 69 6e 67  46 69 65 6c 64 74 00 12    ..string Fieldt..
    4c 6a 61 76 61 2f 6c 61  6e 67 2f 53 74 72 69 6e    Ljava/la ng/Strin
    67 3b 78 70 00 01 7d f1  74 00 05 67 79 79 79 79    g;xp..}. t..gyyyy
    仔细观察二进制串中的部分可读数据,我们也可以差不多分辨出该对象的一些基本内容。但同样为了手写的目的 (为什么有这个目的?原因很简单,为了不被语言环境束缚) ,以及为接下来的序列化执行流程分析做准备,我们先依次来解读一下这个二进制串中的各个元素。
    0xaced,魔术头
    0x0005,版本号 (JDK主流版本一致,下文如无特殊标注,都以JDK8u为例)
    0x73,对象类型标识 (0x7n基本上都定义了类型标识符常量,但也要看出现的位置,毕竟它们都在可见字符的范围,详见java.io.ObjectStreamConstants)
    0x72,类描述符标识
    0x0011...,类名字符串长度和值 (Java序列化中的UTF8格式标准)
    0xd9353cf7d60ac6d5,序列版本唯一标识 (serialVersionUID,简称SUID)
    0x02,对象的序列化属性标志位,如是否是Block Data模式、自定义writeObject(),Serializable、Externalizable或Enum类型等
    0x0002,类的字段个数
    0x49,整数类型签名的第一个字节,同理,之后的0x4c为字符串类型签名的第一个字节 (类型签名表示与JVM规范中的定义相同)
    0x0008...,字段名字符串长度和值,非原始数据类型的字段还会在后面加上数据类型标识、完整类型签名长度和值,如之后的0x740012...
    0x78 Block Data结束标识
    0x70 父类描述符标识,此处为null
    0x00017df1 整数字段intField的值 (Java序列化中的整数格式标准) ,非原始数据类型的字段则会按对象的方式处理,如之后的字符串字段stringField被识别为字符串类型,输出字符串类型标识、字符串长度和值
    由此可以看出,除了基本格式和一些整数表现形式上的不同之外,Java和PHP的序列化结果还是存在很多相似的地方,比如除了具体值外都会对类型进行描述。
    需要注意的是,Java序列化中对字段进行封装时,会按原始和非原始数据类型排序 (有同学可能想问为什么要这么做,这里我只能简单解释原因有两个,一是因为它们两个的表现形式不同,原始数据类型字段可以直接通过偏移量读取固定个数的字节来赋值;二是在封装时会计算原始类型字段的偏移量和总偏移量,以及非原始类型字段的个数,这使得反序列化阶段可以很方便的把原始和非原始数据类型分成两部分来处理) ,且其中又会按字段名排序。
    而开头固定的0xaced0005也可以作为Java序列化二进制串 (Base64编码为rO0AB...) 的识别标识。
    让我们把这个对象再改复杂些:
    class SerializationSuperClass implements Serializable {
        private String superField;
    }
    class SerializationComponentClass implements Serializable {
        private String componentField;
    }
    public class SerializationDemo extends SerializationSuperClass implements Serializable {
        private SerializationComponentClass component;
        // omit

    [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]  下一页

    【声明】:太阳集团2138备用网址(http://www.r-island.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@www.r-island.com,我们会在最短的时间内进行处理。