千家信息网

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

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章给大家分享的是有关Java自定义序列化行为的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。正常情况下,一个类实现java序列化很简单,只需要implemen
千家信息网最后更新 2026年11月01日Java自定义序列化行为的示例分析

这篇文章给大家分享的是有关Java自定义序列化行为的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

正常情况下,一个类实现java序列化很简单,只需要implements Serializable接口即可,之后该类在跨jvm的传输过程中会遵照默认java序列化规则序列化和反序列化;不同jvm版本之间序列化方式稍有不同,但基本上都是兼容的。

在某些特殊情况下,可能需要自定义序列化和反序列化的行为,看下面例子:

Java代码

class AbstractSerializeDemo {         private int x, y;             public void init(int x, int y) {             this.x = x;             this.y = y;         }             public int getX() {             return x;         }             public int getY() {             return y;         }             public void printXY() {             System.out.println("x:" + x + ";y:" + y);         }     }         public class SerializeDemo extends AbstractSerializeDemo implements Serializable {         private int z;             public SerializeDemo() {             super.init(10, 50);             z = 100;         }             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自定义序列化行为的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

序列 对象 代码 方法 值域 行为 两个 示例 分析 不同 内容 子类 情况 更多 程序 篇文章 结果 传输 保证 期望 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中智农互联网科技 上海卓越科技互联网 广州百单互联网科技有限公司 广州凡科互联网科技 互联网科技咨询 中正互联网科技招聘 湖南诚度互联网科技有限公司 佳云科技和互联网广告 成都铂石互联网科技做什么的 互联网科技与管理 崇明区互联网教育科技售后服务 互联网科技人工智能实验室 燊美集互联网科技有限公司 威龙国际互联网科技公司 互联网科技包装股份有限公司上市 广州梦谷互联网科技有限公司领导 陕西九四连强互联网科技有限公司 北京天晋互联网科技有限公司 第三届互联网大会安防黑科技 互联网科技品牌 广州万易互联网科技有限公司 广州紫鲸互联网科技有限公司 广州互联网科技公司 礼当家互联网科技 互联网科技股有哪些 互联网还是高科技吗 浙江互联网科技研学营 互联网科技公司实习生 陕西云淼互联网科技公司 互联网对科技影响
0