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