Java序列化的相关问题

序列化是网络传输不可避免的问题,所以,想要进阶高级Java,弄懂网络通信,Java序列化知识是第一步。

  • 序列化对象 
/**
 * 父类如果没有实现序列化接口,则其父类属性不会被保存在子类中,要想将父类对象也序列化,
 * 就需要让父类也实现Serializable 接口。如果父类不实现的话的,就需要有默认的无参的构造函数。
 * 而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。
 * 在父类无参构造函数中对变量进行初始化。
 */
public class Person implements Serializable{//序列化只保存对象的状态,和类状态无关
	private static final long serialVersionUID = 1L;//唯一标识该对象,如果序列化后对此值修改,反序序列化时报错,类似单向加密
	private String name;
	public static int age;//序列化并不保存静态变量
	private transient String adress;//transient 变量不序列化
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", adress=" + adress + "]";
	}
	public static int getAge() {
		return age;
	}
	public static void setAge(int age) {
		Person.age = age;
	}
	public String getAdress() {
		return adress;
	}
	public void setAdress(String adress) {
		this.adress = adress;
	}
}
  •  序列化测试代码
public class Serialize {

	public static void main(String[] args) throws Exception {
		Person person = new Person();
		person.setAdress("成都");
		person.setName("小明");
		Person.age=26;
		serializePerson(person);
		deserializePerson();

	}
	public static void serializePerson(Person person) throws Exception {
		ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("person")));
		oos.writeObject(person);
		oos.flush();
		System.out.println("第一次序列化成功,大小为"+new File("person").length());
		
		//通过查看person二进制文件可知,只是最后追加了5个字节的引用
		person.setName("小红");//反序列化后的名字并没有改变
		oos.writeObject(person);
		System.out.println("第二次序列化成功,大小为"+new File("person").length());
		oos.close();
	}
	
	public static void deserializePerson() throws Exception {
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("person")));
		Person person = (Person)ois.readObject();
		Person person1 = (Person)ois.readObject();
		//Person person2 = (Person)ois.readObject();//序列化几次,则最多反序列化几次,否则报错 java.io.EOFException
		
		System.out.println("两个对象是否是同一个:"+(person==person1));//true
		Person.age=30;
		System.out.println("反序列化结果"+person);//Person [name=小明, adress=null]
		System.out.println("年龄:"+Person.age);
	}

}
  • 测试结果如下:
第一次序列化成功,大小为77
第二次序列化成功,大小为82
两个对象是否是同一个:true
反序列化结果Person [name=小明, adress=null]
年龄:30

通过查看person二进制文件可知,只是最后追加了5个字节的引用。当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用,上面增加的 5 字节的存储空间就是新增引用和一些控制信息的空间。

转载于:https://my.oschina.net/woniuyi/blog/3053470

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值