java序列化_java对象的序列化和反序列化

----------------------[感谢小郡提供的图片]

1.为什么是序列化

在计算机世界两台机器互相通信,如文本文件,图片,音视频,这些都是以二进制传输的。但是我们想给另一个程序传输java的类对象该怎么办?这时候可以使用序列化将对象序列化(持久化)将数据写入文件,数组然后发送到目的地,转化为序列然后再进行传输,然后再进行解码。

  • 将内存中的对象保存到数据库中
  • 在网络上传输对象
  • 用RMI传输对象的时候

2.如何实现序列化

需要实现Serializable接口即可,并不需要实现内部方法,因为Serializable接口只起标识作用java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中.

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

1、序列化:把对象按照流一样的方式存入文本或者在网络中传输; 对象 ---> 流 :2、反序列化:把文本文件中流对象数据或者网络中流对象数据还原成对象。流---> 对象 :

package day19;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Serialize {


		public static void main(String[] args) throws IOException {
			
			Student stu = new Student("001", "大狗", 20, Gender.男);
			
			/**
			 *	方案1:取stu所有的属性,通过特定的字符串(-),把各个属性值连接起来
			 *  001-大狗-20-男
			 */
			
			File file = new File("F:BaiduNetdiskDownloadC++text.txt");
			FileOutputStream out = new FileOutputStream(file); // 文件输出流
			ObjectOutputStream oos = new ObjectOutputStream(out);//对象序列化流
			
			oos.writeObject(stu);
			
			oos.close();
			out.close();
		}
	}
----------------------Student文件--------------------------------
package day19;


	import java.io.Serializable;

	public class Student implements Serializable {

		//private static final long serialVersionUID = -1003763572517930507L;

		private String id;
		private String name;
		private int age;
		private Gender gender;
		private String phone;

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		public Gender getGender() {
			return gender;
		}

		public void setGender(Gender gender) {
			this.gender = gender;
		}

		public String getPhone() {
			return phone;
		}

		public void setPhone(String phone) {
			this.phone = phone;
		}

		public Student(String id, String name, int age, Gender gender) {
			super();
			this.id = id;
			this.name = name;
			this.age = age;
			this.gender = gender;
		}

		public Student() {
			super();
		}

		@Override
		public String toString() {
			return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
		}
	}

	enum Gender {
		男, 女;
	}
-------------------------反序列化--------------------------------------------
package day19;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test02 {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		
		File file = new File("F:BaiduNetdiskDownloadC++text.txt");
		
		FileInputStream in = new FileInputStream(file);
		ObjectInputStream ois = new ObjectInputStream(in);
		
		Student student = (Student) ois.readObject();
		System.out.println(student.getId());
		System.out.println(student.getName());
		System.out.println(student.getAge());
		System.out.println(student.getGender());
		
		ois.close();
		in.close();
	}
}

40481aad5ec849da247242f03da4eb1b.png
序列化

21d93efcc43644b61221b0f973fa747f.png
反序列化
  • 当序列化完成后,后期升级程序中的类(Student),此时再反序列化时会出现异常。

5b36b445efe33ae198edb771754ef867.png

我把Student的一个实例域(phone)给注释了就会报错误

异常原因:序列化流的serialVersionUID和升级后类的版本不匹配。

解决方案:给Student类加序列化版本号,有两种方式

eclipse会提示你让你给这个类加字段码

79bfc216695e90826f714ca0d1b99e66.png

default serial version ID 生成默认的serial version ID 一般值都是1L。

generated serial version ID 根据当前类的属性、方法生成一个唯一ID。

这个值是final 和 static 意思就是不可改变的常量

9f5d8b6d3da085647fca17913c21ecd8.png

我永transient关键字修饰 private String phone;(静态static的属性,他不序列化。)

3056342c3d8f7f8a20899a39d5fb9987.png

反序列化就看不见phone域(不序列化)

eclipse可能会自动给你赋值个一长串数字。这个是没必要的因为这个值是根据实例域计算出来的具有一定敏感性所以建议自己赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值