JAVA进阶教学之(序列化和反序列化)
目錄
?
1、序列化Serialize和反序列化的概念
2、序列化和反序列化的代碼演示:
3、序列化多個(gè)對(duì)象(序列化集合)
4、transient關(guān)鍵字將部分屬性不參與序列化
?
?
1、序列化Serialize和反序列化的概念
在內(nèi)存和硬盤(pán)的數(shù)據(jù)交互過(guò)程中,將Java對(duì)象拆分的過(guò)程
序列化就是將Java內(nèi)存中的Java對(duì)象切割成像序列一樣傳遞到硬盤(pán)文件中存儲(chǔ) (拆分對(duì)象)
反序列化就是通過(guò)硬盤(pán)序列好的Java對(duì)象組裝重新返回到Java內(nèi)存中(組裝對(duì)象)
?
圖示:
?
2、序列化和反序列化的代碼演示:
序列化:
通過(guò)代碼演示來(lái)加深理解:
首先創(chuàng)建一個(gè)普通的Student學(xué)生類(lèi),這個(gè)學(xué)生類(lèi)沒(méi)有實(shí)現(xiàn)任何接口,就是普通的:
package com.lbj.javase.bean;import java.io.Serializable;public class Student{private int no;private String name;public Student() {}public Student(int no, String name) {this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}//重寫(xiě)toString方法@Overridepublic String toString() {return "Student{" +"no=" + no +", name='" + name + '\'' +'}';} }?
再創(chuàng)建一個(gè)測(cè)試類(lèi),將Student對(duì)象進(jìn)行序列化:
package com.lbj.javase.bean;import java.io.FileOutputStream; import java.io.ObjectOutputStream;public class ObjectOutputStreamTest01{public static void main(String[] args) throws Exception{//創(chuàng)建java對(duì)象Student s=new Student(123,"zhangsan");//包裝類(lèi)FileOutputStream fos=new FileOutputStream("student");//序列化ObjectOutputStream oos=new ObjectOutputStream(fos);//序列化對(duì)象oos.writeObject(s);//刷新oos.flush();//關(guān)閉oos.close();} }報(bào)錯(cuò):
總結(jié):
Student是一個(gè)普通的類(lèi),并不支持序列化,需要加上Serializable的實(shí)現(xiàn)結(jié)構(gòu)
?
?
修改測(cè)試(此時(shí)的Student類(lèi)實(shí)現(xiàn)了Serializable接口):
package com.lbj.javase.bean;import java.io.Serializable;//Serializable只是一個(gè)標(biāo)志性接口,這個(gè)接口其實(shí)什么都不寫(xiě) public class Student implements Serializable {private int no;private String name;public Student() {}public Student(int no, String name) {this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}//重寫(xiě)toString方法@Overridepublic String toString() {return "Student{" +"no=" + no +", name='" + name + '\'' +'}';} }測(cè)試:
package com.lbj.javase.bean;import java.io.FileOutputStream; import java.io.ObjectOutputStream;public class ObjectOutputStreamTest01{public static void main(String[] args) throws Exception{//創(chuàng)建java對(duì)象Student s=new Student(123,"zhangsan");//包裝類(lèi)FileOutputStream fos=new FileOutputStream("student");//序列化ObjectOutputStream oos=new ObjectOutputStream(fos);//序列化對(duì)象oos.writeObject(s);//刷新oos.flush();//關(guān)閉oos.close();} }測(cè)試結(jié)果:
總結(jié):
1、參與序列化和反序列化的對(duì)象,必須實(shí)現(xiàn)Serializable接口
2、Serializable接口只是一個(gè)標(biāo)志性接口,這個(gè)接口中什么也沒(méi)有,只是起到讓java虛擬機(jī)看到這個(gè)類(lèi)實(shí)現(xiàn)了這個(gè)接口,可能對(duì)這個(gè)類(lèi)特殊的待遇,java虛擬機(jī)會(huì)默認(rèn)提供這個(gè)序列化的版本號(hào)(序列化版本號(hào)是用來(lái)區(qū)分序列化的類(lèi)是否發(fā)生改變,用來(lái)達(dá)到安全性)
3、java虛擬機(jī)會(huì)自動(dòng)序列化版本號(hào),缺點(diǎn)。一旦被序列化的類(lèi)A的代碼確定后,不能進(jìn)行后續(xù)的修改;只要修改,必定會(huì)重新編譯,此時(shí)類(lèi)A會(huì)生成全新的序列化版本號(hào),這時(shí)候java虛擬機(jī)會(huì)認(rèn)為這是一個(gè)全新的類(lèi)(這樣就不好了,會(huì)反序列化不成功,因?yàn)榉葱蛄谢歉鶕?jù)序列化版本號(hào)進(jìn)行重新讀取)
4、結(jié)論:凡是一個(gè)類(lèi)實(shí)現(xiàn)了Serializable接口,建議給該類(lèi)一個(gè)固定不變的序列化版本號(hào),這樣,以后這個(gè)類(lèi)即使代碼修改了,但是版本號(hào)不變,java虛擬機(jī)會(huì)認(rèn)為是同一個(gè)類(lèi)(Idea中可以生成一個(gè)序列化版本號(hào),自己去探索,或者自己寫(xiě)一個(gè)也行)(P756)
?
?
-----------------------------------------------------------------------------------------------------------------------------------
?
反序列化:
代碼演示:
package com.lbj.javase.bean;import java.io.FileInputStream; import java.io.ObjectInputStream;public class ObjectInputStreamTest01 {public static void main(String[] args) throws Exception{//包裝類(lèi)FileInputStream fis=new FileInputStream("student");//序列化ObjectInputStream ois=new ObjectInputStream(fis);//開(kāi)始反序列化,讀Object obj=ois.readObject();//輸出obj內(nèi)容//反序列化回來(lái)是一個(gè)學(xué)生對(duì)象,所以會(huì)調(diào)用學(xué)生對(duì)象的toString方法System.out.println(obj.toString());//關(guān)閉流ois.close();} }輸出結(jié)果:
Student{no=123, name='zhangsan'}
?
?
3、序列化多個(gè)對(duì)象(序列化集合)
代碼演示:
創(chuàng)建一個(gè)實(shí)現(xiàn)Serializeable接口的Student類(lèi):
package com.lbj.javase.bean;import java.io.Serializable;//Serializable只是一個(gè)標(biāo)志性接口,這個(gè)接口其實(shí)什么都不寫(xiě) public class Student implements Serializable {private int no;private String name;public Student() {}public Student(int no, String name) {this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}//重寫(xiě)toString方法@Overridepublic String toString() {return "Student{" +"no=" + no +", name='" + name + '\'' +'}';} }?
序列化:
package com.lbj.javase.bean;import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List;public class ObjectOutputStreamTest02 {public static void main(String[] args) throws Exception{//創(chuàng)建一個(gè)集合對(duì)象List<Student> list=new ArrayList<>();//添加集合數(shù)據(jù)list.add(new Student(111,"lisi"));list.add(new Student(222,"Wanwu"));list.add(new Student(333,"liliu"));//輸出流FileOutputStream fos=new FileOutputStream("students");//序列化ObjectOutputStream oos=new ObjectOutputStream(fos);//序列化一個(gè)集合,這個(gè)杰輝對(duì)象中放了很多其他對(duì)象oos.writeObject(list);//刷新流oos.flush();//關(guān)閉流oos.close();} }?
反序列化:
package com.lbj.javase.bean;import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.List;public class ObjectInputStreamTest02 {public static void main(String[] args) throws Exception{//輸入流FileInputStream fis=new FileInputStream("students");//反序列化ObjectInputStream ois=new ObjectInputStream(fis);// Object obj=ois.readObject(); // System.out.println(obj.toString());//用列表形式輸出List<Student> list = (List<Student>) ois.readObject();//集合的循環(huán)輸出for (Student s:list) {System.out.println(s);}//關(guān)閉流ois.close();} }?
結(jié)果:
Student{no=111, name='lisi'}
Student{no=222, name='Wanwu'}
Student{no=333, name='liliu'}
?
?
注意:如果不用集合,直接存儲(chǔ)多個(gè)對(duì)象,在存儲(chǔ)第二個(gè)對(duì)象的時(shí)候會(huì)報(bào)錯(cuò)
?
?
4、transient關(guān)鍵字將部分屬性不參與序列化
transient表示游離的,不參與序列化,只要給屬性加上此限制,即可
演示:
結(jié)果(數(shù)據(jù)變成null):
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的JAVA进阶教学之(序列化和反序列化)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python可变参数和关键字参数位置_p
- 下一篇: 卸载后以前拍的视频会删除吗_可立拍!苹果