引言
在學習IO流時,我們會學到一個序列化流,和反序列化流,相信不少小伙伴學到這個是有些懵的,今天就帶大家來了解一下java的物件序列化流與反序列化流

目錄
一、什么是java的物件序列化流與反序列化流
二、物件的序列化
三、物件的反序列化流
四、物件序列化中我們容易遇到的集合小問題
一、什么是java的物件序列化流與反序列化流
- 物件序列化:就是將物件保存到磁盤中,或者在網路中傳輸物件
Java 提供了一種物件序列化的機制,該機制中,一個物件可以被表示為一個位元組序列,該位元組序列包括該物件的資料、有關物件的型別的資訊和存盤在物件中資料的型別,
將序列化物件寫入檔案之后,可以從檔案中讀取出來,并且對它進行反序列化,也就是說,物件的型別資訊、物件的資料,還有物件中的資料型別可以用來在記憶體中新建物件,
整個程序都是 Java 虛擬機(JVM)獨立的,也就是說,在一個平臺上序列化的物件可以在另一個完全不同的平臺上反序列化該物件,
類 ObjectInputStream 和 ObjectOutputStream 是高層次的資料流,它們包含反序列化和序列化物件的方法,
二、物件的序列化
那么ObjectOutputStream類給我們提供了構造方法和對應的方法,我們只了解他的構造方法和序列化物件的方法,
構造方法

序列化物件方法

了解了它的兩個方法之后,我們來進行代碼演示
這里創建一個學生類,在主方法里面創建一個學生類物件,將學生類物件進行序列化
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\Java\\oos2.txt"));
Student s = new Student("張二狗",22);
oos.writeObject(s);
oos.close();
}
}
當我們寫完代碼之后,點擊運行,會發現爆出一個例外:
java.io.NotSerializableException:
進入幫助檔案查看

說明我們需要在我們的類實作這么一個介面,不然程式就會拋例外,

那么我們接著對類進行實作這介面,
public class Student implements Serializable{
實作該介面以后,我們的程式就不會拋出例外了,此外我們這實作介面后發現不用重寫介面中的方法,打開幫助檔案查看才知道原來該類沒有方法,僅用于序列化的標識,也就是說,在進行物件序列化時,必須要實作該介面,

此時我們的檔案當中的內容

可以發現我們的物件已經被寫進去,但是我們看不懂怎么辦?別慌,往下看看物件的反序列化流,
三、物件的反序列化流
前面我們已經講了反序列化就是把我們檔案中的物件再讀取出來進行反序列化,那么怎么操作呢,這里也使用到了ObjectInputStream類的構造方法和他的讀取方法
構造方法

讀取方法

代碼實作
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/*
構造方法:
ObjectInputStream?(InputStream in):創建從指定的InputStream讀取的ObjectInputStream
反序列化物件的方法:
Object readObject?():從ObjectInputStream讀取一個物件
*/
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException,ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\Java\\oos2.txt"));
Object obj = ois.readObject();
Student s = (Student)obj;
System.out.println(s);
ois.close();
}
}
這時的輸出結果
Student{name='張二狗', age=22}
就變成了我們能看得懂了,
四、物件序列化中我們容易遇到的集合小問題
1.當我們修改類檔案的內容時,會出現一個問題,例如我們現在給學生類中添加一個equals方法,他就會拋出一個例外,
java.io.InvalidClassException: com.Student; local class incompatible: stream classdesc serialVersionUID = -3743788623620386195, local class serialVersionUID = -247282590948908173
遠程UID
stream classdesc serialVersionUID = -3743788623620386195,
本地UID
local class serialVersionUID = -247282590948908173
這個例外在幫助檔案是這樣描述的
那么很明顯我的類不具備三個問題中的后兩個,那么只能是第一個問題了,怎么解決呢,看幫助檔案

也就是說我們修改類檔案時無意把他的那個版本號更改了,那么怎么避免被更改呢,這里就給我們指出了一個方法
private static final long serialVersionUID = -3743788623620386195L;
即在物件的類檔案中加入該屬性來宣告,且該欄位必須是static,final,long型別的
2.如果我們不想類中某一個物件被序列化,可以在類的宣告處加上一個transient
private String name;
// private int age;
private transient int age;
private static final long serialVersionUID = -3743788623620386195L;
Student{name='張二狗', age=0}
可以看到年齡沒有被序列化,這里顯示是因為我重寫的toString方法加上age的默認值是0;
感謝大家的閱讀,喜歡的可以關注我,后面會陸續給大家帶來更多的分享,也歡迎大家在評論區友好交流,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/350917.html
標籤:java
上一篇:【Java】內部類的定義
下一篇:java 8 Stream(流)
