引言:
序列化是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^程,在序列化期間,對(duì)象將其帶你過去的狀態(tài)寫入到臨時(shí)或持儲(chǔ)存區(qū),反序列化就是重新創(chuàng)建對(duì)象的過程,此對(duì)象來自于臨時(shí)或持久儲(chǔ)存區(qū)。
序列化的作用:
就好比如存儲(chǔ)數(shù)據(jù)到數(shù)據(jù)庫,將一些數(shù)據(jù)持久化到數(shù)據(jù)庫中,而有時(shí)候需要將對(duì)象持久化,雖然說將對(duì)象狀態(tài)持久化的方式有很多,但是java給我們提供了一種很便捷的方式,那就是序列化,序列化可以實(shí)現(xiàn)對(duì)象到文件之間的直接轉(zhuǎn)換,實(shí)現(xiàn)細(xì)節(jié)對(duì)我們隱藏。
具體的三種用途:
•將對(duì)象的狀態(tài)信息持久化保存到硬盤上
•將對(duì)象信息在網(wǎng)絡(luò)上傳輸
•深度克?。ň褪切蛄谢笤俜葱蛄谢?/p>
方式一:實(shí)現(xiàn)Serializable接口,通過序列化流
實(shí)現(xiàn)Serializable接口,通過ObjectOutputStream和ObjectInputStream將對(duì)象序列化和反序列化。
import java.io.*;public class User implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '/'' + ", age=" + age + '}'; } public static void main(String[] args) throws IOException, ClassNotFoundException {// User user = new User("gol",22);// ByteArrayOutputStream bo = new ByteArrayOutputStream();// ObjectOutputStream oo = new ObjectOutputStream(bo);// oo.writeObject(user);//序列化.user寫入字節(jié)數(shù)組流中// ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());// ObjectInputStream oi = new ObjectInputStream(bi);// User userSer = (User) oi.readObject();//反序列化// System.out.println(userSer); User user = new User("gol",22); FileOutputStream fos = new FileOutputStream("a.txt"); ObjectOutputStream oo = new ObjectOutputStream(fos); oo.writeObject(user);//序列化.user寫入文件中 FileInputStream fis = new FileInputStream("a.txt"); ObjectInputStream oi = new ObjectInputStream(fis); User userSer = (User) oi.readObject();//反序列化 System.out.println(userSer); oi.close(); fis.close(); oo.close(); fos.close(); }}
方式二:實(shí)現(xiàn)Externalizable接口,重寫writeExternal和readExternal方法
Externalizable接口繼承了Serializable接口,替我們封裝了兩個(gè)方法,一個(gè)用于序列化,一個(gè)用于反序列化。這種方式是將屬性序列化,注意這種方式transient修飾詞將失去作用,也就是說被transient修飾的屬性,只要你在writeExternal方法中序列化了該屬性,照樣也會(huì)得到序列化。
import java.io.*;public class User implements Externalizable { private static final long serialVersionUID = 1L; private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '/'' + ", age=" + age + '}'; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(this.name);//將屬性分別序列化 out.writeObject(this.age); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.name=(String)in.readObject();//反序列化屬性 this.age=(int)in.readObject(); } public static void main(String[] args) throws IOException, ClassNotFoundException { FileOutputStream fos = new FileOutputStream("a.txt"); ObjectOutputStream oo = new ObjectOutputStream(fos); FileInputStream fis = new FileInputStream("a.txt"); ObjectInputStream oi = new ObjectInputStream(fis); User user = new User("gol",19); user.writeExternal(oo);//序列化 User userEnr = new User(); userEnr.readExternal(oi);//反序列化 System.out.println(userEnr); oi.close(); fis.close(); oo.close(); fos.close(); }}
總結(jié):
注意以下三點(diǎn):
•Serializable接口是標(biāo)記接口,是個(gè)空接口,用于標(biāo)識(shí)該類可以被序列化。
•transient是屬性修飾符,被其修飾的屬性將不會(huì)被序列化,但是使用方式二的話,明確寫明該屬性序列化同樣可以得到序列化。
•serialVersionUID屬性是類的序列化標(biāo)識(shí)ID,若序列化的對(duì)象和反序列化的對(duì)象其serialVersionUID屬性不一樣則會(huì)報(bào)錯(cuò)。
新聞熱點(diǎn)
疑難解答
圖片精選