本文为原创文章,欢迎转载,但请注明出处http://www.cnblogs.com/yexiubiao/p/5014015.html,未在文章页面明显位置给出原文连接的,将保留追究法律责任的权利。

通过java的ObjectOutputStream、ObjectInputStream类能对实现了Serializable接口的对象实现序列化与反序列化,如下

import java.io.Serializable;

import com.alibaba.fastjson.JSON;

public class Person implements Serializable{

private static final long serialVersionUID = 1L;

private int id;

private String name;

public Person() {

super();

}

public Person(int id, String name) {

super();

this.id = id;

this.name = name;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String toString() {

// 这里偷懒用了Fastjson

return JSON.toJSONString(this);

}

}

序列化(写入对象):

反序列化(读取对象)

通过这样就能把一个对象存入磁盘里,并且能读取到内存里

以上是Serializable的基本用法,接下来介绍一些使用中的小细节(关于以下出现的术语,保存对象与序列化,读取对象与反序列化都分别是同一个意思)。

1,将对象序列化到本地后,对类进行修改,增加或减少字段(成员变量)或交换字段位置,然后反序列化之前保存的对象,都不会报错。

例如去掉id字段并增加newValue字段:

此时能正常读取之前序列化的对象(newValue字段因为值是null,这里默认不展示):

2,改变serialVersionUID值后,读取时发生异常

java.io.InvalidClassException: com.ye.test.model.Movie; Incompatible class (SUID): com.ye.test.model.Movie: static final long serialVersionUID =1L; but expected com.ye.test.model.Movie: static final long serialVersionUID =2L;

因为serialVersionUID值改变后,类定义的版本变化了,所以读取老版本对象将可能不兼容新对象,因此系统抛出异常

读取为null:

3,保存的时候对象有serialVersionUID,然后删除这个字段,再次读取

则读取时serialVersionUID会被赋值一个自动生成的值

这个值根据类的成员变量方法定义等算出,增减成员变量或者增减方法都会导致这个值的改变

但是如果增加空格,交换成员变量位置等都不会导致这个值被改变

java.io.InvalidClassException: com.ye.test.model.Movie; Incompatible class (SUID): com.ye.test.model.Movie: static final long serialVersionUID =1L; but expected com.ye.test.model.Movie: static final long serialVersionUID =-6926675519878447654L;

也就是说,如果我们的Person类没有声明serialVersionUID变量,则以后这个类只要涉及到增减成员变量或者增减方法都会导致读取对象时不兼容。当然方法位置的调整不会影响。

4,如果先序列化保存一个对象到磁盘,然后修改这个类的定义,将其继承至一个基类(基类没有实现Serializable接口),则会报错

java.io.InvalidClassException: com.ye.test.model.BaseMovie; IllegalAccessException

at java.io.ObjectStreamClass.resolveConstructorClass(ObjectStreamClass.java:692)

如果基类实现了Serializable接口,则能正常读取

5,如果基类已经实现了Serializable接口,则子类无需再次实现(当然子类再次实现也没关系)

6,父类的serialVersionUID成员变量对子类没有影响,即使他是public的,所以反序列化时能不能兼容只会跟子类的serialVersionUID对象数值相关。

也就是说开发中如果我们定义的类已经修改,需要告诉系统我们的类已经不再兼容老版本,则需要修改子类的serialVersionUID版本号而不是父类。

7,如果子类实现Serializable接口,父类没有实现,则只可以执行序列化,不能执行反序列化,执行反序列化时报错信息同4

总结:

1,如果存在继承关系,则只需在基类实现Serializable接口即可

2,serialVersionUID变量需在子类定义,父类定义没有意义(父类定义serialVersionUID用来消除编译警告信息也没关系)

3,如果没有定义serialVersionUID变量,则系统在保存或读取时会根据类结构自动算出一个值赋予serialVersionUID,如果类结构没有变化,那么这个值则是固定的,所以还是尽量使用自定义的值比较便于维护。

4,如果需求变更导致类结构调整,那么如果需要继续读取老版本对象的话, 则不要修改serialVersionUID的版本号,如果需要使用全新的数据而抛弃之前保存在磁盘里的对象,则修改serialVersionUID版本号,系统会默认读取为null。相当于之前没有保存过。

最后附上demo,有兴趣的话可以自己测试下。

java的serializable_Java里Serializable的那些事相关推荐

  1. Java中有关Null的9件事

    对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...

  2. 一种Java Spring框架里将配置文件里定义的值注入到Java变量的简单办法

    假设我在classpath下的application.properties里定义了一些配置: 我想让这些配置自动注入到我Java代码里某个变量中去.最简单的方式就是使用注解@PropertySourc ...

  3. Eclipse Java类编辑器里出现乱码的解决方案

    如图:在Java Class编辑器里出现的这种乱码,非常烦人. 解决方案:Windows->Preference->General->Appearance, 在里面将Theme设置成 ...

  4. Java中Map里put方法的返回值

    在java中,Map里的put方法,如果key值不存在,则返回值是null,但是key值如果存在,则会返回原先被替换掉的value值.(当然,map中的key和value都允许是null). Map ...

  5. JAVA GC(Garbage Collection)及OOM那些事

    2019独角兽企业重金招聘Python工程师标准>>> JAVA运行时内存区域 程序计数器 一块很小的内存空间 当前线程所执行的字节码的行号指示器 当前线程私有 不会出现OutOfM ...

  6. java 往excel中写数据库,poi将数据写入excel表格-怎么用java把数据库里的数据写入到excel表中...

    怎么用java把数据库里的数据写入到excel表中 你是想读取excel内容,然后整合一下数据,然后再生成一个新的excel吧 package aa; import java.io.FileInput ...

  7. 用java里的junit框架_使用Java JUnit框架里的@SuiteClasses注解管理测试用例

    使用Java JUnit框架里的@SuiteClasses注解管理测试用例 发布时间:2020-08-13 13:43:08 来源:ITPUB博客 阅读:96 作者:i042416 Suppose y ...

  8. Java泛型 T extends Serializable

    Java泛型 T extends Serializable 前言 泛型是jdk1.5引入的特性,为了定义参数的类型,代替Object,实现隐式转换. < T extends Serializab ...

  9. java parcelable list_Android中Serializable和Parcelable序列化对象详解

    学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Parcelable进行序列化操作 5.P ...

最新文章

  1. PC上安装MAC X Lion
  2. 攻防世界web题ics-06(爆破id值)
  3. 为什么人们常说“十个创业九个死”?
  4. kafka+线程池+Runnable
  5. js,vue 上传图片前压缩图片(无损压缩,保持在2M以内)
  6. java 200以内的素数_Java——200以内的质数
  7. ArcEngine中的ICommand和ITool
  8. 张钹院士:清华大学AI研究院要孵化人工智能界的BAT
  9. ActionScript 3.0 杂乱笔记3
  10. 我所理解的 iOS 并发编程
  11. Android Studio实现内容丰富的旅游App
  12. 中山LED芯片IC方案!JLC1041, JLK105系列两款超实用
  13. 【AI面试】L1 loss、L2 loss和Smooth L1 Loss,L1正则化和L2正则化
  14. bootStrap dropdown button
  15. scipy中的imread,imresize怎么用
  16. 【ES6】阮一峰ES6学习之迭代器和for...of循环
  17. 【观察】亚信科技:中期业绩逆势上扬,让5G新价值挺进纵深
  18. React 之导入 Excel
  19. 英语三级笔译注意的要点
  20. 安科瑞低压电动机回路抗晃电解决方案

热门文章

  1. sql还原数据库备份数据库_有关数据库备份,还原和恢复SQL面试问题–第IV部分
  2. 【设计模式】 模式PK:命令模式VS策略模式
  3. 362. Design Hit Counter
  4. 自定义cell的左侧滑动
  5. BDT在Mac(10.8.3)下找不到libfreetype.6.dylib
  6. koa2 mysql 中间件_koa2中间件
  7. 简历javaweb项目描述怎么写_简历要怎么写
  8. 第一个Polymer应用 - (2)创建你自己的元素
  9. java对redis的基本操作(初识)
  10. 项目“”受源代码管理,向源代码管理注册此项目时出错。。