关于序列化Serializable接口的问题
老师 您好~就是我在看到序列化与反序列化就自己扩展了一下,有几个问题没能想明白想向老师请教一下~
1. 自己在网上查到要i进行把一个对象通过io读写到本地文件就要实现这个接口,否则就会报非可序列化的异常,那我看源码这个接口里面也没有啥方法也没啥东西,说是JVM就看下标记,实现这个接口就当做标记。
问题一:那这个接口啥东西都没有它何德何能不让人家序列化?
问题二:它底层到底做了什么?
2.在反序列化的时候,要定义一个serialVersionUID,我看官方的api上说可以不定义也可以自己生成一个,然后说是通过这个serialVersionUID来找那个类去加载这个对象。
问题一:那我可不可以理解为序列化的时候有个ID然后经过序列化后这个ID信息就在文件里面存着了然后再进行反序列化的时候就照着这个ID信息找,看那个类里面的ID跟这个一样,然后就用这个类去加载这个对象?
问题二:如果问题一成立,那是不是就是我用一个类去序列化后这个id是30L 然后我反序列化的时候把这个类的ID改为非30L然后再另外一个类上定义这个ID为30L,那么是不是就可以用另外一个类去反序列化这个文件为一个对象?
老师您能为我解答下吗?谢谢~
正在回答
同学你好,1、Serializable接口的作用就是导入序列化接口,引入Serializable是为了利用序列化的技术用于序列化的对象,便于在网络中传输和保存数据。
1)、Serializable序列化接口中没有任何方法或者字段,它只是用于标识可序列化的语义。
2)、在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序列化,序列化就是变成二进制流。
比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,同理,序列化可以理解为这个举手标识,告诉JVM,让JVM将对象变成二进制流。
综上所述,如果没有实现Serializable接口,就不会实现对象的序列化。
2、
1)、是的,JVM是根据SerializableUID来判断一个类的版本,SerializableUID也叫做流标识符(Stream Unique Identifier),即类的版本定义的,它可以显示声明也可以隐式声明。
隐示声明:编译器在编译的时候生成。生成依据通过包名、类名、继承关系、非私有的方法和属性,以及参数、返回值等诸多因子算出来的,极度复杂,基本上计算出来的这个值是唯一的。显示声明格式如下(可以避免对象的不一致导致反序列化报错)
private static final long serialVersionUID = 7111078431122519129L;
2)、可能存在这个情况,比如 我的类对象改变不大,对应的serialVersionUID也没有变化,此时可能出现JVM把以前的对象反序列化回来,就是依据显示声明的serialVersionUID,向JVM撒谎说"类(类对象)版本没有变化",如此编写的类就实现了向上兼容。
这种情况也是可能出现的。
另外,如果直接将一个对象序列化后的内容反序列化为另一个类型的对象,会因为属性等不一致直接抛出异常。
祝学习愉快~
- 参与学习 人
- 提交作业 9393 份
- 解答问题 16556 个
综合就业常年第一,编程排行常年霸榜,无需脱产即可学习,北上广深月薪过万 无论你是未就业的学生还是想转行的在职人员,不需要基础,只要你有梦想,想高薪
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星