Java 序列化高级篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36890813/article/details/89046751

我们只知道类实现Serializable 或者Externalizable就能实现序列化,存储在本地。但是多了解一些总是有好处。

一、序列化ID

序列化ID=属性名+时间戳,反序列化的前提是序列化ID得相同。Eclipse提供两种产生序列化ID的方法,一种是:属性名+时间戳,另一种是我们一般用1L表示。
设计模式中有Faced模式。
在这里插入图片描述

  • S:服务器
  • C:客户端
  • D:通过D对象才能访问a和b
  • a:a类业务逻辑
  • b:b类业务逻辑

客户端的D对象是服务端序列化穿过来,在客户端反序列化得到的。如果服务端对D进行更新,更新后把序列ID更改,更改后客户端的序列ID与服务端序列ID不同,所以反序列化失败,则需要服务端再序列化D传到客户端。依此完成更新。

二、序列化中的静态变量

结论:序列化存储的是对象的状态,类的状态不存储。

public class MainTest implements Externalizable {
	private static String userName = "张三";

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
		out.writeUTF(userName);
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
		System.out.println(in.readUTF());
	}

	public static void main(String[] args) throws Exception {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\java.txt")));
		oos.writeObject(new MainTest());
		MainTest.userName = "李四";
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\java.txt")));
		MainTest obj = (MainTest) ois.readObject();
		oos.close();
		ois.close();
		System.out.println(obj.userName);

	}

}

结果是
李四

三、加密解密

比如准备给password序列化时将她加密后序列化,反序列化后解密对照密匙将它解密。

四、子类序列化时父类的情况

父类没实现Serializable接口那么,子类序列化时父类不会序列化。当反序列化变为对象时,因为子类对象创建会先创建父类,所以会调用父类的构造方法。子类对象的属性的值存在,父类对象的属性的值为0或者为null。

五、序列化存储两次同一对象

public class MainTest implements Externalizable {
	private String userName;

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
	}

	public static void main(String[] args) throws Exception {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\java.txt")));
		MainTest t = new MainTest();
		oos.writeObject(t);
		oos.flush();
		System.out.println(new File("d:\\java.txt").length());
		oos.writeObject(t);
		System.out.println(new File("d:\\java.txt").length());
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\java.txt")));
		MainTest obj = (MainTest) ois.readObject();
		MainTest obj1 = (MainTest) ois.readObject();
		oos.close();
		ois.close();
		System.out.println(obj == obj1);

	}

}

结果
40
45
true
读取了两次都是同一对象。并且存储两次应该存储空间变为两倍,这里只增加了5,因为存储第二次时只存储对象的引用加控制信息。

六、存储两次相同对象,第二次存储改变属性值

public class MainTest implements Serializable {
	String userName;

	public static void main(String[] args) throws Exception {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:\\java.txt")));
		MainTest t = new MainTest();
		t.userName = "张三";
		oos.writeObject(t);
		oos.flush();
		t.userName = "李四";
		oos.writeObject(t);
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:\\java.txt")));
		MainTest obj = (MainTest) ois.readObject();
		MainTest obj1 = (MainTest) ois.readObject();
		oos.close();
		ois.close();
		System.out.println(obj.userName);
		System.out.println(obj1.userName);

	}

}

结果为
张三
张三
因为两个存储同一对象,只会存储第一次对象。第二次值存储对象的引用和控制信息。

猜你喜欢

转载自blog.csdn.net/qq_36890813/article/details/89046751