国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

java中對(duì)象的序列化與反序列化深入講解

2024-07-14 08:42:22
字體:
供稿:網(wǎng)友

引言:

序列化就是一種用來處理對(duì)象流的機(jī)制,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化。可以對(duì)流化后的對(duì)象進(jìn)行讀寫操作,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決在對(duì)對(duì)象流進(jìn)行讀寫操作時(shí)所引發(fā)的問題。

  • 把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化。
  • 把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。

在很多應(yīng)用中,需要對(duì)某些對(duì)象進(jìn)行序列化,讓它們離開內(nèi)存空間,入住物理硬盤,以便長(zhǎng)期保存。比如最常見的是Web服務(wù)器中的Session對(duì) 象,當(dāng)有 10萬用戶并發(fā)訪問,就有可能出現(xiàn)10萬個(gè)Session對(duì)象,內(nèi)存可能吃不消,于是Web容器就會(huì)把一些seesion先序列化到硬盤中,等要用了,再把保存在硬盤中的對(duì)象還原到內(nèi)存中。

當(dāng)兩個(gè)進(jìn)程在進(jìn)行遠(yuǎn)程通信時(shí),彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個(gè)Java對(duì)象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為Java對(duì)象。

序列化是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^程,在序列化期間,對(duì)象將其帶你過去的狀態(tài)寫入到臨時(shí)或持儲(chǔ)存區(qū),反序列化就是重新創(chuàng)建對(duì)象的過程,此對(duì)象來自于臨時(shí)或持久儲(chǔ)存區(qū)。

序列化的作用:

就好比如存儲(chǔ)數(shù)據(jù)到數(shù)據(jù)庫(kù),將一些數(shù)據(jù)持久化到數(shù)據(jù)庫(kù)中,而有時(shí)候需要將對(duì)象持久化,雖然說將對(duì)象狀態(tài)持久化的方式有很多,但是java給我們提供了一種很便捷的方式,那就是序列化,序列化可以實(shí)現(xiàn)對(duì)象到文件之間的直接轉(zhuǎn)換,實(shí)現(xiàn)細(xì)節(jié)對(duì)我們隱藏。

具體的三種用途:

  • 將對(duì)象的狀態(tài)信息持久化保存到硬盤上
  • 將對(duì)象信息在網(wǎng)絡(luò)上傳輸
  • 深度克隆(就是序列化后再反序列化)

方式一:實(shí)現(xiàn)Serializable接口,通過序列化流

實(shí)現(xiàn)Serializable接口,通過ObjectOutputStream和ObjectInputStream將對(duì)象序列化和反序列化。

import java.io.*;public class User implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public User(String name, int age) {  this.name = name;  this.age = age; } @Override public String toString() {  return "User{" +    "name='" + name + '/'' +    ", age=" + age +    '}'; } public static void main(String[] args) throws IOException, ClassNotFoundException {//  User user = new User("gol",22);//  ByteArrayOutputStream bo = new ByteArrayOutputStream();//  ObjectOutputStream oo = new ObjectOutputStream(bo);//  oo.writeObject(user);//序列化.user寫入字節(jié)數(shù)組流中//  ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());//  ObjectInputStream oi = new ObjectInputStream(bi);//  User userSer = (User) oi.readObject();//反序列化//  System.out.println(userSer);  User user = new User("gol",22);  FileOutputStream fos = new FileOutputStream("a.txt");  ObjectOutputStream oo = new ObjectOutputStream(fos);  oo.writeObject(user);//序列化.user寫入文件中  FileInputStream fis = new FileInputStream("a.txt");  ObjectInputStream oi = new ObjectInputStream(fis);  User userSer = (User) oi.readObject();//反序列化  System.out.println(userSer);  oi.close();  fis.close();  oo.close();  fos.close(); }}

方式二:實(shí)現(xiàn)Externalizable接口,重寫writeExternal和readExternal方法

Externalizable接口繼承了Serializable接口,替我們封裝了兩個(gè)方法,一個(gè)用于序列化,一個(gè)用于反序列化。這種方式是將屬性序列化,注意這種方式transient修飾詞將失去作用,也就是說被transient修飾的屬性,只要你在writeExternal方法中序列化了該屬性,照樣也會(huì)得到序列化。

import java.io.*;public class User implements Externalizable { private static final long serialVersionUID = 1L; private String name; private int age; public User() { } public User(String name, int age) {  this.name = name;  this.age = age; } @Override public String toString() {  return "User{" +    "name='" + name + '/'' +    ", age=" + age +    '}'; } @Override public void writeExternal(ObjectOutput out) throws IOException {  out.writeObject(this.name);//將屬性分別序列化  out.writeObject(this.age); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {  this.name=(String)in.readObject();//反序列化屬性  this.age=(int)in.readObject(); } public static void main(String[] args) throws IOException, ClassNotFoundException {  FileOutputStream fos = new FileOutputStream("a.txt");  ObjectOutputStream oo = new ObjectOutputStream(fos);  FileInputStream fis = new FileInputStream("a.txt");  ObjectInputStream oi = new ObjectInputStream(fis);  User user = new User("gol",19);  user.writeExternal(oo);//序列化  User userEnr = new User();  userEnr.readExternal(oi);//反序列化  System.out.println(userEnr);  oi.close();  fis.close();  oo.close();  fos.close(); }}

總結(jié):

注意以下三點(diǎn):

  • Serializable接口是標(biāo)記接口,是個(gè)空接口,用于標(biāo)識(shí)該類可以被序列化。
  • transient是屬性修飾符,被其修飾的屬性將不會(huì)被序列化,但是使用方式二的話,明確寫明該屬性序列化同樣可以得到序列化。
  • serialVersionUID屬性是類的序列化標(biāo)識(shí)ID,若序列化的對(duì)象和反序列化的對(duì)象其serialVersionUID屬性不一樣則會(huì)報(bào)錯(cuò)。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)VeVb武林網(wǎng)的支持。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 河池市| 康乐县| 济源市| 乌拉特后旗| 姜堰市| 邻水| 内乡县| 茂名市| 宜兰市| 郁南县| 华蓥市| 临邑县| 仁布县| 青河县| 济宁市| 遂宁市| 洪湖市| 利辛县| 武安市| 湟中县| 英山县| 左权县| 会东县| 洞头县| 山丹县| 四会市| 永寿县| 康平县| 茶陵县| 汤阴县| 克什克腾旗| 浦北县| 新密市| 无极县| 莎车县| 汝南县| 嘉鱼县| 南澳县| 余庆县| 腾冲县| 澜沧|