日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对象流及序列化

發布時間:2025/5/22 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对象流及序列化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 對象流
  • 序列化:
    • 序列化的特點:
    • serialVersionUID:序列化版本號
    • 序列化的過程
  • 反序列化:
    • 反序列化的過程:
  • 補充:


前言

使用對象和磁盤打交道的IO類是ObjectInputStream和ObjectOutputStream
而序列化和反序列化是對象是否可以使用對象流的關鍵


對象流

ObjectInputStream:對象輸入流:存入到磁盤中一個對象實體
ObjectOutputStream:對象輸出流:從瓷盤中取出一個對象實體
注意:對象流操作的對象需要 實現序列化。

序列化:

將對象實例保存到磁盤的過程就是序列化(ObjectOutputStream)

序列化的特點:

1、對象要能完成序列化和反序列化的對象必須實現Serializable接口 2、序列化和反序列化需要使用到IO類ObjectInputStream和ObjectOutputStream 3、虛擬機是否能支持序列化,也需要取決于serialVersionUID值 4、transient關鍵字是來控制變量的序列化,在變量前加關鍵,當前的變量不參與序列化,反序列化中 transient關鍵字修飾的變量會給定初始值 如:int類型0,對象類型給定null值 5、要將父類對象也參與序列化,則就需要讓父類對象實現實現Serializable接口

serialVersionUID:序列化版本號

serialVersionUID是一個標識符,通常在對象的哈希碼序列化時會標記在對象上
serialVersionUID生成方式:
1、一般可以是默認值1
2、另一種是類名、接口名、成員方法和屬性等生成的64位的哈希字段
作用是進行版本控制,當對類添加或者修改類中的任何字段,已經序列化的對象將無法恢復,因為類已經生成新的serialVersionUID,在進行反序列化時,會將當前類的serialVersionUID和序列化的對象的serialVersionUID進行比較,如果不匹配,將拋出異常

序列化的過程

ObjectOutputStream outputStream = null;try {outputStream = new ObjectOutputStream(new FileOutputStream(path));outputStream.writeObject(o);outputStream.flush();} catch (IOException e) {e.printStackTrace();} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}

反序列化:

將對象從磁盤中讀取出來的過程是反序列化(ObjectInputStream)

反序列化的過程:

ObjectInputStream inputStream = null;try {inputStream = new ObjectInputStream(new FileInputStream(path));Person person = (Person) inputStream.readObject();System.out.println(person);} catch (Exception e) {e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}

補充:

為什么Serializable接口沒有任何方法可以完成序列化:
我們通過查看ArrayList源碼來進行分析
在序列化過程中,如果被序列化的類實現了writeObject和readObject方法,虛擬機在調用對象類型的readObject 和writeObject是,會執行到該類中的自定義的方法,如果類里面沒實現自定義的方法的話,ObjectOutputStream會調用默認的defaultWriteObject,或者ObjectInputStream中的defaultInputStream方法

if (obj instanceof String) {writeString((String) obj, unshared);} else if (cl.isArray()) {writeArray(obj, desc, unshared);} else if (obj instanceof Enum) {writeEnum((Enum) obj, desc, unshared);} else if (obj instanceof Serializable) {//判定當前是Serializable實現類writeOrdinaryObject(obj, desc, unshared);} else {if (extendedDebugInfo) {throw new NotSerializableException(cl.getName() + "\n" + debugInfoStack.toString());} else {throw new NotSerializableException(cl.getName());}} Serializable接口提供一個標識,方便底層序列化中調用特定的方法

transient:的作用:
比如:ArrayList中的elementDate屬性使用transient關鍵字修飾
ArrayList是一個動態數組,每次在放滿后都會動態的擴容設定一個長度值,如果設定數據長度為100,而實際存放1個有效數據,那么會序列化99個null元素,為了保證序列化不將99個null值參與序列計劃,ArrayList設定為transient
elementDate在序列化是是將數據取出來進行序列化的

總結

以上是生活随笔為你收集整理的对象流及序列化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。