JAVA對(duì)象的序列化與反序列化(詳細(xì))PPT課件_第1頁
JAVA對(duì)象的序列化與反序列化(詳細(xì))PPT課件_第2頁
JAVA對(duì)象的序列化與反序列化(詳細(xì))PPT課件_第3頁
JAVA對(duì)象的序列化與反序列化(詳細(xì))PPT課件_第4頁
JAVA對(duì)象的序列化與反序列化(詳細(xì))PPT課件_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、對(duì)象的序列化與反序列化 當(dāng)兩個(gè)進(jìn)程進(jìn)行遠(yuǎn)程通信時(shí)當(dāng)兩個(gè)進(jìn)程進(jìn)行遠(yuǎn)程通信時(shí),彼此可以發(fā)送各彼此可以發(fā)送各種類型的數(shù)據(jù)種類型的數(shù)據(jù),包括文本包括文本圖片圖片音頻音頻視頻等視頻等,都都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送. 當(dāng)兩個(gè)當(dāng)兩個(gè)java進(jìn)程進(jìn)行通信時(shí)進(jìn)程進(jìn)行通信時(shí),一個(gè)進(jìn)程能否把一一個(gè)進(jìn)程能否把一個(gè)個(gè)java對(duì)象發(fā)送給另一個(gè)進(jìn)程呢對(duì)象發(fā)送給另一個(gè)進(jìn)程呢?答案是肯定的答案是肯定的! 如何才能做到呢如何才能做到呢 1)發(fā)送方需要把這個(gè)發(fā)送方需要把這個(gè)java對(duì)象轉(zhuǎn)換為字節(jié)序列對(duì)象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)上傳送才能在網(wǎng)上傳送 2)接收方需要把字節(jié)序列再恢復(fù)為接收方需要把

2、字節(jié)序列再恢復(fù)為java對(duì)象對(duì)象. 把把java對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化序列化,. 把字節(jié)序列恢復(fù)為把字節(jié)序列恢復(fù)為java對(duì)象的過程稱為對(duì)象的對(duì)象的過程稱為對(duì)象的反序列化反序列化.序列化與反序列化序列化與反序列化 把對(duì)象的字節(jié)序列永久的保存到硬盤上,把對(duì)象的字節(jié)序列永久的保存到硬盤上,通常存放在一個(gè)文件中通常存放在一個(gè)文件中. 在網(wǎng)絡(luò)上傳送對(duì)象的字節(jié)序列在網(wǎng)絡(luò)上傳送對(duì)象的字節(jié)序列.主機(jī)1主機(jī)2文件網(wǎng)絡(luò)傳輸存儲(chǔ)到文件 如何才能做到呢如何才能做到呢 1)發(fā)送方需要把這個(gè)發(fā)送方需要把這個(gè)java對(duì)象轉(zhuǎn)換為字節(jié)序列對(duì)象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)上傳送才

3、能在網(wǎng)上傳送 2)接收方需要把字節(jié)序列再恢復(fù)為接收方需要把字節(jié)序列再恢復(fù)為java對(duì)象對(duì)象. 把把java對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化序列化,. 把字節(jié)序列恢復(fù)為把字節(jié)序列恢復(fù)為java對(duì)象的過程稱為對(duì)象的對(duì)象的過程稱為對(duì)象的反序列化反序列化.序列化與反序列化序列化與反序列化 java.io.ObjectOutputStream:代表對(duì)象輸出流它的writeObject(Object obj)方法可對(duì)參數(shù)指定的obj對(duì)象進(jìn)行序列化,把得到的字節(jié)序列寫到一個(gè)目標(biāo)輸出流中。Java.io.ObjectInputStream代表對(duì)象輸入流,它的readO

4、bject()方法從一個(gè)源輸入流中讀取字節(jié),再把它們反序列化成一個(gè)對(duì)象,并將其返回。哪些類可以被序列化呢? 只有實(shí)現(xiàn)了Serializable或Externalizable接口的類的對(duì)象才能被序列化,否則ObjectOutputStream的writeObject(Object obj)方法會(huì)拋出IOException。實(shí)現(xiàn)了Serializable或Externalizable接口的類也稱為可序列化類。Externalizable接口繼承Serializable接口,實(shí)現(xiàn)Externalizable接口的類完全由自身來控制序列化的行為。而僅實(shí)現(xiàn)Serializable接口的類可以采用默認(rèn)的序

5、列化方式。Jdk的部分類 如StringDate等都實(shí)現(xiàn)了Serializable接口假定一個(gè)Customer類,它的對(duì)象需要序列化。 可以有以下三種方式進(jìn)行如果customer類僅僅實(shí)現(xiàn)了Serializable接口的類,那么會(huì)按照以下方式進(jìn)行序列化和反序列化:ObjectOutputStream采用默認(rèn)的序列化方式,對(duì)Customer對(duì)象的非transient的實(shí)例變量進(jìn)行序列化。1.ObjectInputStream采用默認(rèn)的反序列化方式,對(duì)customer對(duì)象的非transient的實(shí)例變量進(jìn)行反序列化。2. 如果customer類僅僅實(shí)現(xiàn)了Serializable接口,并且還定義了r

6、eadObject(ObjectInputStream in)和writeObject(ObjectOutputStream out),那么會(huì)按照以下方式進(jìn)行序列化和反序列化:ObjectOutputStream會(huì)調(diào)用Customer對(duì)象的writeObject(ObjectOutputStream out)方法進(jìn)行序列化。ObjectInputStream會(huì)調(diào)用Customer對(duì)象的readObject(ObjectInputStream in)方法進(jìn)行反序列化。3. 如果customer類實(shí)現(xiàn)了Externalizable接口,那么Customer類必須實(shí)現(xiàn)readExternal(Obj

7、ectInput in)和writeExternal(ObjectOutput out)方法,那么會(huì)按照以下方式進(jìn)行序列化和反序列化:ObjectOutputStream會(huì)調(diào)用Customer對(duì)象的writeExternal(ObjectOutput out)方法進(jìn)行序列化。ObjectInputStream會(huì)調(diào)用Customer對(duì)象的readExternal(ObjectInput in)方法進(jìn)行反序列化。創(chuàng)建一個(gè)對(duì)象輸出流,它可以包裝一個(gè)其創(chuàng)建一個(gè)對(duì)象輸出流,它可以包裝一個(gè)其他類型的目標(biāo)輸出流,如文件輸出流:他類型的目標(biāo)輸出流,如文件輸出流:ObjectOutputStream out =

8、 new ObjectOutputStream(new fileOutputStream(“D:objectfile.obj”);通過對(duì)象輸出流的通過對(duì)象輸出流的writeObject()方法寫對(duì)象,方法寫對(duì)象,如:如:Out.writeObject(“hello”);Out.writeObject(new Date();創(chuàng)建一個(gè)對(duì)象輸入流,它可以包裝一個(gè)其創(chuàng)建一個(gè)對(duì)象輸入流,它可以包裝一個(gè)其他類型的源輸入流,如文件輸入流:他類型的源輸入流,如文件輸入流:ObjectInputStream in = new ObjectInputStream (new fileIutputStream(“D:

9、objectfile.obj”);通過對(duì)象輸入流的通過對(duì)象輸入流的readObject()方法讀取對(duì)方法讀取對(duì)象,如:象,如:String obj1=(String)in.readObject();Date obj2=(Date)in.readObject();為了能正確讀取數(shù)據(jù),必須保證向?qū)ο筝敒榱四苷_讀取數(shù)據(jù),必須保證向?qū)ο筝敵隽鲗憣?duì)象的順序與從對(duì)象輸入流讀對(duì)象出流寫對(duì)象的順序與從對(duì)象輸入流讀對(duì)象的順序一致的順序一致import java.io.*;import java.util.*;public class ObjectSaver public static void main(St

10、ring agrs) throws Exception ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(D:objectFile.obj); String obj1=hello; Date obj2=new Date(); Customer obj3=new Customer(Tom,20); /序列化對(duì)象序列化對(duì)象 out.writeObject(obj1); out.writeObject(obj2); out.writeObject(obj3); out.writeInt(123); out.close

11、();/反序列化對(duì)象反序列化對(duì)象 ObjectInputStream in=new ObjectInputStream(new FileInputStream(D:objectFile.obj); String obj11 = (String)in.readObject(); System.out.println(obj11:+obj11); System.out.println(obj11=obj1:+(obj11=obj1); Date obj22 = (Date)in.readObject(); System.out.println(obj22:+obj22); System.out.p

12、rintln(obj22=obj2:+(obj22=obj2); Customer obj33 = (Customer)in.readObject(); System.out.println(obj33:+obj33); System.out.println(obj33=obj3:+(obj33=obj3); int var= in.readInt(); System.out.println(var:+var); in.close();class Customer implements Serializable private String name; private int age; pub

13、lic Customer(String name,int age) =name; this.age=age; public String toString()return name=+name+,age=+age; 該服務(wù)器從命令行讀取用戶指定的類名,該服務(wù)器從命令行讀取用戶指定的類名,創(chuàng)建該類的一個(gè)對(duì)象,然后向客戶端兩次創(chuàng)建該類的一個(gè)對(duì)象,然后向客戶端兩次發(fā)送這個(gè)對(duì)象。發(fā)送這個(gè)對(duì)象。 結(jié)果表明:按照默認(rèn)方式序列化時(shí),如果結(jié)果表明:按照默認(rèn)方式序列化時(shí),如果有一個(gè)有一個(gè)ObjectOutputStream對(duì)象多次序列化同對(duì)象多次序列化同一個(gè)對(duì)象,那么有一個(gè)一個(gè)對(duì)象,那么有一個(gè)

14、ObjectInputStream對(duì)對(duì)象反序列化出來的對(duì)象也是同一個(gè)對(duì)象。象反序列化出來的對(duì)象也是同一個(gè)對(duì)象。import java.io.*;import .*;import java.util.*;public class SimpleServer public void send(Object object)throws IOException ServerSocket serverSocket = new ServerSocket(8000); while(true) Socket socket=serverSocket.accept(); OutputStream out=socke

15、t.getOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(out); oos.writeObject(object); oos.writeObject(object); oos.close(); socket.close(); public static void main(String args)throws IOException Object object=null; if(args.length0 & args0.equals(Date) object=new Date(); else if(args.

16、length0 & args0.equals(Customer1) object=new Customer1(Tom,1234); else if(args.length0 & args0.equals(Customer2) Customer2 customer=new Customer2(Tom); Order2 order1=new Order2(number1,customer); Order2 order2=new Order2(number2,customer); customer.addOrder(order1); customer.addOrder(order2)

17、; object=customer; else if(args.length0 & args0.equals(Customer3) object=new Customer3(Tom,1234); else if(args.length0 & args0.equals(Customer4) Customer4 customer=new Customer4(Tom); Order4 order1=new Order4(number1,customer); Order4 order2=new Order4(number2,customer); customer.addOrder(or

18、der1); customer.addOrder(order2); object=customer; else if(args.length0 & args0.equals(Customer5) object=new Customer5(Tom,25); else object=Hello; System.out.println(待發(fā)送的對(duì)象信息:待發(fā)送的對(duì)象信息:+object); new SimpleServer().send(object);import java.io.*;import .*;import java.util.*;public class SimpleClien

19、t public void receive()throws Exception Socket socket = new Socket(localhost,8000); InputStream in=socket.getInputStream(); ObjectInputStream ois=new ObjectInputStream(in); Object object1=ois.readObject(); Object object2=ois.readObject(); System.out.println(object1); System.out.println(object2); Sys

20、tem.out.println(object1與與object2是否為同一個(gè)對(duì)象是否為同一個(gè)對(duì)象: +(object1=object2); public static void main(String args)throws Exception new SimpleClient().receive(); ObjectOutputStream只能對(duì)實(shí)現(xiàn)了只能對(duì)實(shí)現(xiàn)了Serializable接口的類的對(duì)象進(jìn)行序列化,接口的類的對(duì)象進(jìn)行序列化, 默認(rèn)情況下,默認(rèn)情況下, ObjectOutputStream按照默認(rèn)按照默認(rèn)方式進(jìn)行序列化,這種方式只能對(duì)對(duì)象的方式進(jìn)行序列化,這種方式只能對(duì)對(duì)象的非非t

21、ransient的實(shí)例變量進(jìn)行序列化,而不會(huì)的實(shí)例變量進(jìn)行序列化,而不會(huì)序列化對(duì)象的序列化對(duì)象的transient的實(shí)例變量和靜態(tài)變的實(shí)例變量和靜態(tài)變量,例如例程量,例如例程9-4public class Customer1 implements Serializable private static int count; /用于計(jì)算用于計(jì)算Customer對(duì)象的數(shù)目對(duì)象的數(shù)目 private static final int MAX_COUNT=1000; private String name; private transient String password; static Syste

22、m.out.println(調(diào)用調(diào)用Customer1類的靜態(tài)代碼塊類的靜態(tài)代碼塊); public Customer1() System.out.println(調(diào)用調(diào)用Customer1類的不帶參數(shù)的構(gòu)造方法類的不帶參數(shù)的構(gòu)造方法); count+; public Customer1(String name, String password) System.out.println(調(diào)用調(diào)用Customer1類的帶參數(shù)的構(gòu)造方法類的帶參數(shù)的構(gòu)造方法); =name; this.password=password; count+; public String toString

23、() return count=+count + MAX_COUNT=+MAX_COUNT + name=+name + password=+ password; 先運(yùn)行先運(yùn)行”java SimpleServer Customer1”,再運(yùn)行命令再運(yùn)行命令“java SimpleClient ”,服務(wù)器端打印的結(jié)果如下:服務(wù)器端打印的結(jié)果如下:調(diào)用調(diào)用Customer1類的靜態(tài)代碼塊類的靜態(tài)代碼塊調(diào)用調(diào)用Customer1類的帶參數(shù)的構(gòu)造方法類的帶參數(shù)的構(gòu)造方法待發(fā)送的對(duì)象信息:待發(fā)送的對(duì)象信息:count=1 MAX_COUNT=1000 name=Tom password=1234客戶端打

24、印的信息(反序列化時(shí)不會(huì)調(diào)用類的構(gòu)客戶端打印的信息(反序列化時(shí)不會(huì)調(diào)用類的構(gòu)造方法)造方法)調(diào)用調(diào)用Customer1類的靜態(tài)代碼塊類的靜態(tài)代碼塊count=0 MAX_COUNT=1000 name=Tom password=nullcount=0 MAX_COUNT=1000 name=Tom password=nullObject1與與Object2是否為同一個(gè)對(duì)象:是否為同一個(gè)對(duì)象:true先運(yùn)行先運(yùn)行”java SimpleServer Customer1”,再運(yùn)行命令再運(yùn)行命令“java SimpleClient ”,服務(wù)器端打印的結(jié)果如下:服務(wù)器端打印的結(jié)果如下:調(diào)用調(diào)用Cust

25、omer1類的靜態(tài)代碼塊類的靜態(tài)代碼塊調(diào)用調(diào)用Customer1類的帶參數(shù)的構(gòu)造方法類的帶參數(shù)的構(gòu)造方法待發(fā)送的對(duì)象信息:待發(fā)送的對(duì)象信息:count=1 MAX_COUNT=1000 name=Tom password=1234客戶端打印的信息(反序列化時(shí)不會(huì)調(diào)用類的構(gòu)客戶端打印的信息(反序列化時(shí)不會(huì)調(diào)用類的構(gòu)造方法)造方法)調(diào)用調(diào)用Customer1類的靜態(tài)代碼塊類的靜態(tài)代碼塊count=0 MAX_COUNT=1000 name=Tom password=nullcount=0 MAX_COUNT=1000 name=Tom password=nullObject1與與Object2是否

26、為同一個(gè)對(duì)象:是否為同一個(gè)對(duì)象:true類與類之間可能存在關(guān)聯(lián)關(guān)系。如例程類與類之間可能存在關(guān)聯(lián)關(guān)系。如例程9-5,customer2與與order2之間存在一對(duì)多的雙向關(guān)之間存在一對(duì)多的雙向關(guān)聯(lián)關(guān)系聯(lián)關(guān)系public class Customer2 implements Serializable private String name; private Set orders=new HashSet(); static System.out.println(調(diào)用調(diào)用Customer2類的靜態(tài)代碼塊類的靜態(tài)代碼塊); public Customer2() System.out.println(調(diào)

27、用調(diào)用Customer2類的不帶參數(shù)的構(gòu)造方法類的不帶參數(shù)的構(gòu)造方法); public Customer2(String name) System.out.println(調(diào)用調(diào)用Customer2類的帶參數(shù)的構(gòu)造方法類的帶參數(shù)的構(gòu)造方法); =name; public void addOrder(Order2 order) orders.add(order); public String toString() String result=super.toString()+rn+orders+rn; return result; class Order2 implements

28、 Serializable private String number; private Customer2 customer; public Order2() System.out.println(調(diào)用調(diào)用Order2類的不帶參數(shù)的構(gòu)類的不帶參數(shù)的構(gòu)造方法造方法); public Order2(String number,Customer2 customer) System.out.println(調(diào)用調(diào)用Order2類的帶參數(shù)的構(gòu)造類的帶參數(shù)的構(gòu)造方法方法); this.number=number; this.customer=customer; 在例程在例程9-2中以下代碼建立了他們的關(guān)

29、聯(lián)關(guān)系:中以下代碼建立了他們的關(guān)聯(lián)關(guān)系:else if(args.length0 & args0.equals(Customer2) Customer2 customer=new Customer2(Tom); Order2 order1=new Order2(number1,customer); Order2 order2=new Order2(number2,customer); customer.addOrder(order1); customer.addOrder(order2); object=customer; Customer2對(duì)象Order2對(duì)象Order2對(duì)象序列化序

30、列化customer2對(duì)象時(shí)是否會(huì)序列化與它對(duì)象時(shí)是否會(huì)序列化與它關(guān)聯(lián)的對(duì)象呢?關(guān)聯(lián)的對(duì)象呢?序列化對(duì)象時(shí),會(huì)序列化對(duì)象序列化對(duì)象時(shí),會(huì)序列化對(duì)象customer2以以及所有從及所有從customer2直接或間接導(dǎo)航到的對(duì)直接或間接導(dǎo)航到的對(duì)象。象。Customer2對(duì)象Order2對(duì)象Order2對(duì)象如果用戶希望控制序列化行為,可以在序列化如果用戶希望控制序列化行為,可以在序列化類中提供以下方法:類中提供以下方法:private void writeObject(ObjectOutputStream ou)在該方法中可以調(diào)用在該方法中可以調(diào)用ObjectOutputStream擁有的擁有的d

31、efaultWriteObject(ObjectOutputStream ou),使得,使得對(duì)象輸出流先執(zhí)行默認(rèn)的序列化操作對(duì)象輸出流先執(zhí)行默認(rèn)的序列化操作private void readObject(ObjectInputStream in)1.在該方法中同樣可以調(diào)用在該方法中同樣可以調(diào)用ObjectInputStream的的defaultReadObject()方法。方法。以下情況下,可以考慮用戶自定義的序列以下情況下,可以考慮用戶自定義的序列化方式,從而控制序列化行為:化方式,從而控制序列化行為:確保序列化安全性,對(duì)敏感信息加密后再確保序列化安全性,對(duì)敏感信息加密后再序列化,反序列化時(shí)

32、需解密。序列化,反序列化時(shí)需解密。確保對(duì)象的成員變量符合正確的約束條件確保對(duì)象的成員變量符合正確的約束條件優(yōu)化序列化的性能。優(yōu)化序列化的性能。1.便于更好的封裝類的內(nèi)部數(shù)據(jù)結(jié)構(gòu),確保便于更好的封裝類的內(nèi)部數(shù)據(jù)結(jié)構(gòu),確保類的接口不會(huì)被類的內(nèi)部實(shí)現(xiàn)所束縛類的接口不會(huì)被類的內(nèi)部實(shí)現(xiàn)所束縛import java.io.*;public class Customer3 implements Serializable private static int count; /用于計(jì)算用于計(jì)算Customer3對(duì)象的數(shù)目對(duì)象的數(shù)目 private static final int MAX_COUNT=1000;

33、 private String name; private transient String password; static System.out.println(調(diào)用調(diào)用Customer3類的靜態(tài)代碼塊類的靜態(tài)代碼塊); public Customer3() System.out.println(調(diào)用調(diào)用Customer3類的不帶參數(shù)的構(gòu)造方法類的不帶參數(shù)的構(gòu)造方法); count+; public Customer3(String name, String password) System.out.println(調(diào)用調(diào)用Customer3類的帶參數(shù)的構(gòu)造方法類的帶參數(shù)的構(gòu)造方法); t

34、=name; this.password=password; count+; 序列化的序列化的安全性安全性/* 加密數(shù)組,將加密數(shù)組,將buff數(shù)組中的每個(gè)字節(jié)的每一位取反數(shù)組中的每個(gè)字節(jié)的每一位取反 * 例如例如13的二進(jìn)制為的二進(jìn)制為00001101,取反后為,取反后為11110010 */ private byte change(byte buff) for(int i=0;ibuff.length;i+) int b=0; for(int j=0;jj & 1)=0 ? 1:0; b+=(1j)*bit; buffi=(byte)b; return buff;

35、private void writeObject(ObjectOutputStream stream)throws IOException stream.defaultWriteObject(); /先按默認(rèn)方式序列化先按默認(rèn)方式序列化 stream.writeObject(change(password.getBytes(); stream.writeInt(count); private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException stream.defaultRea

36、dObject(); /先按默認(rèn)方式反序列化先按默認(rèn)方式反序列化 byte buff=(byte)stream.readObject(); password = new String(change(buff); count=stream.readInt(); public class Customer implements Serializable private int age; public Customer(int age) if(age0) /合法性檢查合法性檢查 throw new IllegalArgumentException(年齡不能小于零年齡不能小于零); this.age=age; public String toString() return age=+age; pr

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論