想象一下,你剛開始玩一個遊戲,一進遊戲,首先系統提示你需要建立一個角色。
新建角色物件:姓名(宇宙第一無敵厲害)誰會取這樣的名字哈哈哈、性別、門派、等級......
建完角色之後,來到新手村,對於一個心懷大俠夢的有志青年當然不能被困在這小小的新手村了,所以你需要去刷boss
攢經驗升級。
boss
物件:血量、等級、擁有技能......
就這樣,經過不懈努力,你終於達到了能出新手村的等級。這時候,夜深了,你媽氣急敗壞叫你關電腦睡覺。大家都知道,建立的物件是儲存在記憶體中的,記憶體中的資料斷電即失。難道剛要出新手村,大俠夢就破滅了?怎麼辦呢?
二、大俠夢持續輸出——序列化
為了不讓無數青年的大俠夢關機即碎,序列化技術出現了,在遊戲中的體現就是存檔。即,在退出遊戲的時候,點選存檔按鈕,這時候,你遊戲角色的等級,裝備等都會被儲存在儲存媒體中(硬碟等)。這時候,就算你關機了,下次再次登入遊戲,還是你關機時儲存的角色狀態。
總結:序列化就是將記憶體中的物件資料儲存到儲存媒體中。
三、小爺我又回來了——反序列化
當天晚上,你在你媽的壓迫下無奈關機睡覺了。第二天起來你迫不及待開啟遊戲準備再次大幹一場,可是遊戲角色已經被序列化到硬碟中,怎麼取出來呢?這時候,反序列化技術就出現了。就是把你存在硬碟上的資料還原成原來的遊戲物件,該是多少級還是多少級,該是啥裝備就是啥裝備。
總結:反序列化就是將儲存在媒體中的物件還原成記憶體中物件。
序列化與反序列化擴充套件:
對於序列化來講,不單單是作為將記憶體中的資料儲存到媒體中,其網路傳輸也是一大作用。
你想想,玩遊戲當然是大家一起玩才好了。每個遊戲玩家在遊戲世界中都可以進行溝通交流,當你刷boss
的時候,爆到了一把一刀999的屠龍寶刀。這時候,你可以選擇高價賣給遊戲的其他土豪玩家。這時候,你不可能直接通過網線把這個給人家,而是通過序列化的方法,把這把屠龍刀傳輸給買家,買家在接收到這個資料之後,再通過反序列化將這把寶刀還原。
即,序列化的作用:
儲存記憶體中的物件、進行網路傳輸。
四、序列化機制探究
上文說到,序列化可以進行網路傳輸,說到網路傳輸,那麼I/O
就不能陌生了,I/O
傳輸支援的資料格式是位元組陣列。即,要想進行網路傳輸,就是將傳輸的物件轉換成位元組陣列。但是,我們不能盲目隨便轉換成位元組陣列,因為你後面還需要將物件進行還原。也就是說,在進行轉換的時候你要指定一個規則(序列化),在將物件轉換成位元組陣列的時候按照這個規則進行轉換。那個將物件進行還原的時候,按照規則(反序列化)進行還原。你不能將一個人偶拆了之後,裝的時候,把手裝成腳。
即,序列化機制:
將物件轉換成位元組陣列的時候的轉換規則,這種轉換規則就是序列化機制。
五、序列化的種類
原生的JDK
JDK
自帶了序列化方法,只需要實現了Serializable
介面的類,就可以通過ObjectOutputStream
類將物件變成byte[]位元組陣列。
弊端:只能java
自己玩。
程式碼示例:
/** * @ClassName Student * @Description Student類物件 * @Author LH * @Date 2022/6/12 10:32 */ @Data public class Student implements Serializable { private String id; private String name; private int age; }
/** * @ClassName JDKSerialize * @Description JDK序列化介面測試 * @Author LH * @Date 2022/6/12 10:41 */ public class JDKSerialize { /** * 物件序列化 * @param student 學生物件 * @throws IOException 丟擲io異常 */ public static void serializeStudent(Student student) throws IOException { ObjectOutputStream oo = new ObjectOutputStream(new ObjectOutputStream(Files.newOutputStream(new File("E:/java/workplace/study/student.txt").toPath()))); oo.writeObject(student); oo.close(); } /** * 物件反序列化 * @param path 反序列化檔案路徑 * @return Student 還原的學生物件 * @throws IOException 丟擲io異常 * @throws ClassNotFoundException 找不到檔案異常 */ public static Student deSerializeStudent(String path) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new ObjectInputStream(Files.newInputStream(new File(path).toPath()))); Student student = (Student) ois.readObject(); ois.close(); return student; } public static void main(String[] args) { // 建立一個student物件 Student student = new Student(); student.setId("1"); student.setName("LH"); student.setAge(17); try { // 序列化student物件 JDKSerialize.serializeStudent(student); // student物件飯序列化 String path = "E:/java/workplace/study/student.txt"; Student deSerializeStudent = JDKSerialize.deSerializeStudent(path); System.out.println("student id:" + deSerializeStudent.getId() + "student age:" + deSerializeStudent.getAge() + "student name:" + deSerializeStudent.getName()); } catch (Exception e) { e.printStackTrace(); } } }
ProtoBuf
谷歌推出,一種語言無關、平臺無關、可擴充套件的序列化結構資料的方法,可用於通訊協議、資料儲存等。序列化後體積小,一般用於對傳輸效能有較高要求的系統。
瞭解不是很多,後面工作用到的話再來進行擴充套件。
JSON
在系統之間進行互動的時候很常用。
JSON
序列化方式生成的是一串有規則的字串,可讀性強。是有規則的字串,不跟任何程式語言繫結,天然上就具備了跨平臺。
弊端:體積大。
常見的工具有:
fastJSON
、Jackson
、Gson
等。工作中比較常用的就是阿里的fastJSON,使用起來也很簡單,直接呼叫轉換的api即可,瞭解更多可以去官網看看。
各種序列化手段都有不同的特性,看你的業務再去選型。
序列化如何選擇
主要考慮三點:
-
選擇的序列化手段是否需要跨平臺
-
選擇的序列化手段的速度要求
-