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 + "]";
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章