摘要:序列化機(jī)制使得對(duì)象可以脫離程序的運(yùn)行而獨(dú)立存在。普通序列化接口是一個(gè)標(biāo)記接口,不用實(shí)現(xiàn)任何方法。如果此對(duì)象已經(jīng)序列化過(guò),則直接輸出編號(hào)即可。圖示上述序列化過(guò)程。
一、序列化的含義、意義及使用場(chǎng)景二、序列化實(shí)現(xiàn)的方式1、Serializable1.1 普通序列化1.2 成員是引用的序列化1.3 同一對(duì)象序列化多次的機(jī)制1.4 java序列化算法潛在的問(wèn)題1.5 可選的自定義序列化2、Externalizable:強(qiáng)制自定義序列化3、兩種序列化對(duì)比三、序列化版本號(hào)serialVersionUID四、總結(jié)
一、序列化的含義、意義及使用場(chǎng)景如果需要將某個(gè)對(duì)象保存到磁盤(pán)上或者通過(guò)網(wǎng)絡(luò)傳輸,那么這個(gè)類(lèi)應(yīng)該實(shí)現(xiàn)Serializable接口或者Externalizable接口之一。
Serializable接口是一個(gè)標(biāo)記接口,不用實(shí)現(xiàn)任何方法。一旦實(shí)現(xiàn)了此接口,該類(lèi)的對(duì)象就是可序列化的。
步驟一:創(chuàng)建一個(gè)ObjectOutputStream輸出流;
步驟二:調(diào)用ObjectOutputStream對(duì)象的writeObject輸出可序列化對(duì)象。
public class Person implements Serializable {
private String name;
private int age;
//我不提供無(wú)參構(gòu)造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name=" + name + +
", age=" + age +
};
}
}
public class WriteObject {
public static void main(String[] args) {
try (//創(chuàng)建一個(gè)ObjectOutputStream輸出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
//將對(duì)象序列化到文件s
Person person = new Person("9龍", 23);
oos.writeObject(person);
} catch (Exception e) {
e.printStackTrace();
}
}
}
步驟一:創(chuàng)建一個(gè)ObjectInputStream輸入流;
步驟二:調(diào)用ObjectInputStream對(duì)象的readObject()得到序列化的對(duì)象。
我們將上面序列化到person.txt的person對(duì)象反序列化回來(lái)
public class Person implements Serializable {
private String name;
private int age;
//我不提供無(wú)參構(gòu)造器
public Person(String name, int age) {
System.out.println("反序列化,你調(diào)用我了嗎?");
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name=" + name + +
", age=" + age +
};
}
}
public class ReadObject {
public static void main(String[] args) {
try (//創(chuàng)建一個(gè)ObjectInputStream輸入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
Person brady = (Person) ois.readObject();
System.out.println(brady);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//輸出結(jié)果
//Person{name=9龍, age=23}
waht);
如果一個(gè)可序列化的類(lèi)的成員不是基本類(lèi)型,也不是String類(lèi)型,那這個(gè)引用類(lèi)型也必須是可序列化的;否則,會(huì)導(dǎo)致此類(lèi)不能序列化。
看例子,我們新增一個(gè)Teacher類(lèi)。將Person去掉實(shí)現(xiàn)Serializable接口代碼。
public class Person{
//省略相關(guān)屬性與方法
}
public class Teacher implements Serializable {
private String name;
private Person person;
public Teacher(String name, Person person) {
this.name = name;
this.person = person;
}
public static void main(String[] args) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("teacher.txt"))) {
Person person = new Person("路飛", 20);
Teacher teacher = new Teacher("雷利", person);
oos.writeObject(teacher);
}
}
}
我們看到程序直接報(bào)錯(cuò),因?yàn)镻erson類(lèi)的對(duì)象是不可序列化的,這導(dǎo)致了Teacher的對(duì)象不可序列化
同一對(duì)象序列化多次,會(huì)將這個(gè)對(duì)象序列化多次嗎?答案是否定的。
public class WriteTeacher {
public static void main(String[] args) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("teacher.txt"))) {
Person person = new Person("路飛", 20);
Teacher t1 = new Teacher("雷利", person);
Teacher t2 = new Teacher("紅發(fā)香克斯", person);
//依次將4個(gè)對(duì)象寫(xiě)入輸入流
oos.writeObject(t1);
oos.writeObject(t2);
oos.writeObject(person);
oos.writeObject(t2);
}
}
}
依次將t1、t2、person、t2對(duì)象序列化到文件teacher.txt文件中。
注意:反序列化的順序與序列化時(shí)的順序一致。
public class ReadTeacher {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("teacher.txt"))) {
Teacher t1 = (Teacher) ois.readObject();
Teacher t2 = (Teacher) ois.readObject();
Person p = (Person) ois.readObject();
Teacher t3 = (Teacher) ois.readObject();
System.out.println(t1 == t2);
System.out.println(t1.getPerson() == p);
System.out.println(t2.getPerson() == p);
System.out.println(t2 == t3);
System.out.println(t1.getPerson() == t2.getPerson());
} catch (Exception e) {
e.printStackTrace();
}
}
}
//輸出結(jié)果
//false
//true
//true
//true
//true
從輸出結(jié)果可以看出,Java序列化同一對(duì)象,并不會(huì)將此對(duì)象序列化多次得到多個(gè)對(duì)象。
所有保存到磁盤(pán)的對(duì)象都有一個(gè)序列化編碼號(hào)
當(dāng)程序試圖序列化一個(gè)對(duì)象時(shí),會(huì)先檢查此對(duì)象是否已經(jīng)序列化過(guò),只有此對(duì)象從未(在此虛擬機(jī))被序列化過(guò),才會(huì)將此對(duì)象序列化為字節(jié)序列輸出。
如果此對(duì)象已經(jīng)序列化過(guò),則直接輸出編號(hào)即可。
圖示上述序列化過(guò)程。
由于java序利化算法不會(huì)重復(fù)序列化同一個(gè)對(duì)象,只會(huì)記錄已序列化對(duì)象的編號(hào)。如果序列化一個(gè)可變對(duì)象(對(duì)象內(nèi)的內(nèi)容可更改)后,更改了對(duì)象內(nèi)容,再次序列化,并不會(huì)再次將此對(duì)象轉(zhuǎn)換為字節(jié)序列,而只是保存序列化編號(hào)。
public class WriteObject {
public static
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/7113.html
摘要:序列化機(jī)制使得對(duì)象可以脫離程序的運(yùn)行而獨(dú)立存在。普通序列化接口是一個(gè)標(biāo)記接口,不用實(shí)現(xiàn)任何方法。如果此對(duì)象已經(jīng)序列化過(guò),則直接輸出編號(hào)即可。圖示上述序列化過(guò)程。一、序列化的含義、意義及使用場(chǎng)景二、序列化實(shí)現(xiàn)的方式1、Serializable1.1 普通序列化1.2 成員是引用的序列化1.3 同一對(duì)象序列化多次的機(jī)制1.4 java序列化算法潛在的問(wèn)題1.5 可選的自定義序列化2、Extern...
摘要:動(dòng)態(tài)地代理,可以猜測(cè)一下它的含義,在運(yùn)行時(shí)動(dòng)態(tài)地對(duì)某些東西代理,代理它做了其他事情。所以動(dòng)態(tài)代理的內(nèi)容重點(diǎn)就是這個(gè)。所以下一篇我們來(lái)細(xì)致了解下的到底是怎么使用動(dòng)態(tài)代理的。 之前講了《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》,本來(lái)打算下一篇講講Srping的AOP的,但是其中會(huì)涉及到Java的動(dòng)態(tài)代理,所以先單獨(dú)一篇來(lái)了解下Java的動(dòng)態(tài)代理到底是什么,Java是怎么實(shí)現(xiàn)它的。 ...
摘要:序列化機(jī)制使得對(duì)象可以脫離程序的運(yùn)行而獨(dú)立存在。普通序列化接口是一個(gè)標(biāo)記接口,不用實(shí)現(xiàn)任何方法。如果此對(duì)象已經(jīng)序列化過(guò),則直接輸出編號(hào)即可。圖示上述序列化過(guò)程。一、序列化的含義、意義及使用場(chǎng)景二、序列化實(shí)現(xiàn)的方式1、Serializable1.1 普通序列化1.2 成員是引用的序列化1.3 同一對(duì)象序列化多次的機(jī)制1.4 java序列化算法潛在的問(wèn)題1.5 可選的自定義序列化2、Extern...
摘要:手動(dòng)創(chuàng)建執(zhí)行線程存在以上問(wèn)題,而線程池就是用來(lái)解決這些問(wèn)題的。線程池詳解上面我們已經(jīng)知道了線程池的作用,而對(duì)于這樣一個(gè)好用,重要的工具,當(dāng)然已經(jīng)為我們提供了實(shí)現(xiàn),這也是本篇文章的重點(diǎn)。,線程池一旦空閑超過(guò)時(shí)間,線程都將被回收。 showImg(https://segmentfault.com/img/remote/1460000018476903); 本文原創(chuàng)地址,我的博客:https...
摘要:注解在類(lèi)上為類(lèi)提供一個(gè)全參的構(gòu)造方法,加了這個(gè)注解后,類(lèi)中不提供默認(rèn)構(gòu)造方法了。這個(gè)注解用在類(lèi)上,使用類(lèi)中所有帶有注解的或者帶有修飾的成員變量生成對(duì)應(yīng)的構(gòu)造方法。 轉(zhuǎn)載請(qǐng)注明原創(chuàng)地址:http://www.54tianzhisheng.cn/2018/01/07/lombok/ showImg(http://ohfk1r827.bkt.clouddn.com/blog/180107/7...
閱讀 713·2023-04-25 19:43
閱讀 3910·2021-11-30 14:52
閱讀 3784·2021-11-30 14:52
閱讀 3852·2021-11-29 11:00
閱讀 3783·2021-11-29 11:00
閱讀 3869·2021-11-29 11:00
閱讀 3558·2021-11-29 11:00
閱讀 6105·2021-11-29 11:00