Java自定义序列化行为的示例分析

技术Java自定义序列化行为的示例分析这篇文章给大家分享的是有关Java自定义序列化行为的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。正常情况下,一个类实现java序列化很简单,只需

本文将与您分享关于Java自定义序列化行为的示例分析的内容。我觉得边肖很实用,就和大家分享一下作为参考。让我们跟着边肖看一看。

通常情况下,一个类实现java序列化非常简单,只需要实现Serializable接口,然后在跨jvm传输的过程中,根据默认的java序列化规则对该类进行序列化和反序列化。不同的jvm版本有稍微不同的序列化方法,但是它们基本上是兼容的。

在某些特殊情况下,可能需要自定义序列化和反序列化的行为。请参见以下示例:

Java代码

classabstractserializedmo { private intx,y;publicvoidinit(intx,inty){ this . x=x;this.y=y} publiintgetx(){ returnx;} publiintgety(){ returny;} public void prinxy(){ system . out . println(' x : ' x ';y : ' y);} } public class serializedemoextendsabstractserializedemoimplementserializable { privateintz;public serialisedemo(){ super . init(10,50);z=100}nbsp

;            public void printZ() {             super.printXY();             System.out.println("z:" + z);         }             public static void main(String[] args) throws IOException, ClassNotFoundException {             ByteArrayOutputStream bos = new ByteArrayOutputStream();             ObjectOutputStream out = new ObjectOutputStream(bos);             SerializeDemo sd = new SerializeDemo();             sd.printZ();             out.writeObject(sd);             ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));             SerializeDemo sd2 = (SerializeDemo) in.readObject();             sd2.printZ();         }     }

这段程序表示了一个可序列化的类继承自一个非序列化的有状态超类,期望的结果是,子类序列化以后传输并反序列化回来,原先的值域包括超类的值域都保持不变。

但是输出是:

Java代码

x:10;y:50    z:100    x:0;y:0    z:100

结果和期望不符,子类的值域保留下来了,但是超类的值域丢失了,这对jvm来说是正常的,因为超类不可序列化;

为了解决这个问题,只能自定义序列化行为,具体做法是在SerializeDemo里加入以下代码:

Java代码

private void writeObject(ObjectOutputStream os) throws IOException {           os.defaultWriteObject();//java对象序列化默认操作           os.writeInt(getX());           os.writeInt(getY());       }           private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {           is.defaultReadObject();//java对象反序列化默认操作           int x=is.readInt();           int y=is.readInt();           super.init(x,y);       }

writeObject和readObject方法为JVM会在序列化和反序列化java对象时会分别调用的两个方法,修饰符都是private,没错。

我们在序列化的默认动作之后将超类里的两个值域x和y也写入object流;与之对应在反序列化的默认操作之后读入x和y两个值,然后调用超类的初始化方法。

再次执行程序之后的输出为:

Java代码

x:10;y:50    z:100    x:10;y:50    z:100

另外还有两个自定义序列化方法writeReplace和readResolve,分别用来在序列化之前替换序列化对象 和 在反序列化之后的对返回对象的处理。一般可以用来避免singleTon对象跨jvm序列化和反序列化时产生多个对象实例,事实上singleTon的对象一旦可序列化,它就不能保证singleTon了。JVM的Enum实现里就是重写了readResolve方法,由JVM保证Enum的值都是singleTon的,所以建议多使用Enum代替使用writeReplace和readResolve方法。

Java代码

private Object readResolve()         {             return INSTANCE;         }                 private Object writeReplace(){             return INSTANCE;         }

注:writeReplace调用在writeObject前;readResolve调用在readObject之后。

感谢各位的阅读!关于“Java自定义序列化行为的示例分析”这篇文章就分享到这里了,希望

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/133163.html

(0)

相关推荐

  • 如何理解Java设计模式的装饰模式

    技术如何理解Java设计模式的装饰模式这篇文章主要介绍“如何理解Java设计模式的装饰模式”,在日常操作中,相信很多人在如何理解Java设计模式的装饰模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望

    攻略 2021年11月8日
  • 上课用英语怎么说,上课和下课分别用英语怎么说

    技术上课用英语怎么说,上课和下课分别用英语怎么说一、“上课”的英语两种形式:go to class 上课用英语怎么说,give a lesson1、go to class
    英 [ɡəu tu: klɑ:s] 美 [ɡ

    生活 2021年10月29日
  • python如何链接数据库

    技术python如何链接数据库小编给大家分享一下python如何链接数据库,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MySQLdb模块是为

    攻略 2021年11月24日
  • 4.运算符和流程控制

    技术4.运算符和流程控制 4.运算符和流程控制运算符
    在 PHP 中,赋值运算符 = 用于给变量赋值。
    在 PHP 中,算术运算符 + 用于把值加在一起
    1.算数运算符运算符
    名称
    描述
    实例
    结果x

    礼包 2021年12月23日
  • 如何用Python画一个绝美土星环

    技术如何用Python画一个绝美土星环本篇文章为大家展示了如何用Python画一个绝美土星环,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。土星的行星环非常出名。虽然木星、土星、天

    攻略 2021年10月28日
  • React5种非常流行的状态管理库是什么

    技术React5种非常流行的状态管理库是什么本篇内容主要讲解“React 5种非常流行的状态管理库是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React 5种非常流行

    攻略 2021年10月26日