Serializable 序列化笔记

  • 序列化和反序列化是java中进行数据存储和数据传输的一种方式。序列化是把对象转化为字节的过程,反序列化反之。
  • 序列化的场景?
  1. 网络通信中以字节传输
  2. 数据的存储
  • 如何序列化?
  1. 实现Serializable 接口
  2. 实现Externalizable 接口,其中Externalizable 接口继承了Serializable 接口

  • 需求:将User 类序列化到 test.txt 文件中

(1)User 类实现Serializable 接口,添加生成serialVersionUID

public class User implements Serializable {
	
	private static final long serialVersionUID = 7262143984388335055L;
	
	private String name;
	private Integer age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
}

(2)测试类

public class TestSerializable {
	public static void main(String[] args) {
		
		User user = new User();
		user.setName("testname");
		user.setAge(20);
		
		serialize(user);//序列化对象
		
		User u = (User) deserialize();//反序列化
		
		System.out.println(u);
		
	}

	private static void serialize(Serializable sobj) {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.txt"));
			oos.writeObject(sobj);
			oos.flush();
			oos.close();
			
		} catch (Exception e) {
			System.out.println("序列化失败");
			e.printStackTrace();
		}
		System.out.println("序列化成功");
	}
	
	private static Object deserialize() {
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt"));
			Object obj = ois.readObject();
			ois.close();
			System.out.println("反序列化成功");
			return obj;
		} catch (Exception e) {
			System.out.println("反序列化失败");
			e.printStackTrace();
		}
		return null;
	}
}

(3)结果

序列化成功
反序列化成功
User [name=testname, age=20]


  • serialVersionUID 有何作用?

是序列化和反序列化的标识,只有ID 相同才能成功转换。删除serialVersionUID 的情况种,当已经序列化在文件之中,然后修改User 类,之后反序列化会报错。


  • transient 关键字与Externaliable 运用场景
  1. 当User 类很多属性时,只有一个或几个不需要序列化,在属性前添加transient 关键字。
  2. 当User 类很多属性时,只有一个或几个需要序列化时,实现Externalizable 接口来对这个或这些属性序列化。
  • 第一种就不演示了,下面是第二种实现Externalizable 接口,必须重写两个方法,当序列化时会自动调用,测试类不变。

问题:为什么实现 Externalizable 接口不用serialVersionUID ?

Externalizable的反序列化和serializable不一样,它会在反序列化时调用对象的默认构造函数来创建这个对象,然后利用void readExternal(ObjectInput in)中的对相应的属性的进行初始化。如果没有该默认构造函数,会报错。

public class User implements Externalizable {
	
	private String name;
	private Integer age;
	
	/**序列化时自动调用*/
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeUTF(this.name);
		
	}
	/**反序列化时自动调用*/
	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		this.name = in.readUTF();
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
}

运行结果 

序列化成功
反序列化成功
User [name=testname, age=null]


  • 加密后再序列化,反序列化后再解密
public class User implements Serializable {
	
	private static final long serialVersionUID = 7262143984388335055L;
	
	private String name;
	private Integer age;
	
	//调用ObjectOutputStream.writeObject 的时候自动调用
		private void writeObject(ObjectOutputStream oos) throws Exception {
			Base64.Encoder encoder = Base64.getEncoder();	
			byte[] array = encoder.encode(this.name.getBytes());	
			this.name =new String(array);
			oos.defaultWriteObject();
		}
		
		//调用ObjectInputStream.readObject 的时候自动调用
		private void readObject(ObjectInputStream ois) throws Exception {
			ois.defaultReadObject();//先反序列化	
			Base64.Decoder decoder = Base64.getDecoder();
			byte[] bs = decoder.decode(this.name);
			this.name=new String(bs);		
		}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
}

猜你喜欢

转载自blog.csdn.net/pigqhf/article/details/89483502
今日推荐