javaBean為什麼要實現Serializable介面?

来源:http://www.cnblogs.com/lycsky/archive/2016/03/17/5289918.html
-Advertisement-
Play Games

引用:http://jzinfo.javaeye.com/blog/519470 Java的"對象序列化"能讓你將一個實現了Serializable介面的對象轉換成一組byte,這樣日後要用這個對象時候,你就能把這些byte數據恢復出來,並據此重新構建那個對象了。這一點甚至在跨網路的環境下也是如此,...


 

引用:http://jzinfo.javaeye.com/blog/519470

Java的"對象序列化"能讓你將一個實現了Serializable介面的對象轉換成一組byte,這樣日後要用這個對象時候,你就能把這些byte數據恢復出來,並據此重新構建那個對象了。這一點甚至在跨網路的環境下也是如此,這就意味著序列化機制能自動補償操作系統方面的差異。也就是說,你可以在Windows機器上創鍵一個對象,序列化之後,再通過網路傳到Unix機器上,然後在那裡進行重建。你不用擔心在不同的平臺上數據是怎樣表示的,byte順序怎樣,或者別的什麼細節。

對象序列化本身就非常有趣,因為它能讓你實現"輕量級的persistence(lightweight persistence)"。所謂persistence是指,對象的生命周期不是由程式是否運行決定的;在程式的兩次調用之間對象仍然還活著。通過"將做過序列化處理的對象寫入磁碟,等到程式再次運行的時候再把它讀出來",你可以達到persistence的效果。之所以說"輕量級",是因為你不能用像"persistent"這樣的關鍵詞來直接定義一個對象,然後讓系統去處理所有細節(雖然將來有可能會這樣)。相反,你必須明確地進行序列化(serialize)和解序列化(deserialize)。如果你需要更為正式的persistence功能,可以考慮Java Data Object( 簡稱是JDO)或Hibernate之類的工具(http://hibernate.sourceforge.net)。

之所以要在語言裡加入對象序列化是因為要用它來實現兩個重要的功能。Java的遠程方法調用(Remote Method Invocation簡稱RMI)能讓你像調用自己機器上的對象那樣去調用其它機器上的對象。當你向遠程對象傳遞消息的時候,就需通過對象序列化來傳送參數和返回值了。RMI會在Thinking in Enterprise Java作討論。

我們會在第14章講到JavaBean。對JavaBean來說,對象序列化也是必不可少的。Bean的狀態信息通常是在設計時配置的。這些狀態信息必須保存起來,供程式啟動的時候用;對象序列化就負責這個工作。

序列化一個對象還是比較簡單的,只要讓它實現Serializable介面就行了(這是一個"標記介面(tagging interface)",沒有任何方法)。但是,當語言引入序列化概念之後,它的很多標準類庫的類,包括primitive的wrapper類,所有的容器類,以及別的很多類,都會相應地發生改變。甚至連Class對象都會被序列化。

要想序列化對象,你必須先創建一個OutputStream,然後把它嵌進ObjectOutputStream。這時,你就能用writeObject( )方法把對象寫入OutputStream了。讀的時候,你得把InputStream嵌到ObjectInputStream裡面,然後再調用readObject( )方法。不過這樣讀出來的,只是一個Object的reference,因此在用之前,還得先下傳。

對象序列化最聰明的一點是,它不僅能保存對象的副本,而且還會跟著對象裡面的reference,把它所引用的對象也保存起來,然後再繼續跟蹤那些對象的reference,以此類推。這種情形常被稱為"單個對象所聯結的'對象網'"。這個機制所涵蓋的範圍不僅包括對象的成員數據,而且還包含數組裡面的reference。如果你要自己實現對象序列化的話,那麼編寫跟蹤這些鏈接的程式將會是一件非常痛苦的任務。但是,Java的對象序列化就能精確無誤地做到這一點,毫無疑問,它的遍歷演算法是做過優化的。

---------------------------------------------------------------------

實現java.io.Serializable 介面的類是可序列化的。沒有實現此介面的類將不能使它們的任一狀態被序列化或逆序列化。

  序列化類的所有子類本身都是可序列化的。這個序列化介面沒有任何方法和域,僅用於標識序列化的語意。允許非序列化類的子類型序列化,子類型可以假定負責保存和恢復父類型的公有的、保護的和(如果可訪問)包的域的狀態。只要該類(擴展)有一個無參構造子,可初始化它的狀態,那麼子類型就可承擔上述職責。在這種情況下申明一個可序列化的類是一個錯誤。此錯誤將在運行時被檢測。就是可以把對象存到位元組流,然後可以恢復!

  例如:Integer實現了Serializable,所以可以把一個Integer的對象用IO寫到文件里,之後再可以從文件里讀出,如你開始寫入的時候那個對象的intValue() 是5的話,那讀出來之後也是5。這一點體現了用序化類的作用,即用來傳送類的對象。

  當一個JavaBean在構造工具內被用戶化,並與其它Bean建立連接之後,它的所有狀態都應當可被保存,下一次被load進構造工具內或在運行時,就應當是上一次修改完的信息。為了能做到這一點,要把Bean的某些欄位的信息保存下來,在定義Bean時要使它實現Java.io.Serializable介面。例如:

  public class Button implements Java.io.Serializable {……}

  實現了序列化介面的Bean中欄位的信息將被自動保存。若不想保存某些字(這裡的Bean中欄位的信息將被自動保存是什麼意思?這個自動保存是怎麼實現的?)

  段的信息則可在這些欄位前冠以transient或static關鍵字,transient和static變數的信息是不可被保存的。通常,一個Bean所有公開出來的屬性都應當是被保存的,也可有選擇地保存內部狀態。Bean開發者在修改軟體時,可以添加欄位,移走對其它類的引用,改變一個欄位的private、protected或public狀態,這些都不影響類的存儲結構關係。然而,當從類中刪除一個欄位,改變一個變數在類體系中的位置,把某個欄位改成transient/static,或原來是transient/static,現改為別的特性時,都將引起存儲關係的變化。

  所謂的Serializable,就是java提供的通用數據保存和讀取的介面。至於從什麼地方讀出來和保存到哪裡去都被隱藏在函數參數的背後了。這樣子,任何類型只要實現了Serializable介面,就可以被保存到文件中,或者作為數據流通過網路發送到別的地方。也可以用管道來傳輸到系統的其他程式中。這樣子極大的簡化了類的設計。只要設計一個保存一個讀取功能就能解決上面說得所有問題。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Apple 在 iOS 提供了文件共用(FileSharing)功能,讓 App 有一個對外視窗的目錄,透過 iTunes 可以任意管理這個目錄的文檔內容(可拖入文檔,也能將文檔拖出備份)。 如果 App 需要文件共用,只需要在 Delphi 的 Project Option 需要加入 UIFile
  • Linux下,當我們用mysql c api 去操作mysqldb的時候,預設情況下,程式會以Latin1這種字元集去進行sql操作,這種情況,很可能就會出現亂碼, 比如,資料庫設置的字元集是utf8, 然後我們通過程式向其中插入一條記錄,然後我們去查詢的時候,就會出現亂碼。 為瞭解決這個問題,我們
  • 本文主要介紹 Java 泛型的概念和定義,以及 Java 泛型機制的實現原理。 使用泛型程式設計,可以避免隨處可見的 Object 以及強制轉換,提高了代碼的安全性和可讀性。 類型參數(type parameters): Java 和C++一樣,通過引入類型參數進行泛型編程。 泛型類(generic
  • 在前面的討論里我們提到自由數據結構就是產生某種類型的最簡化結構,比如:free monoid, free monad, free category等等。我們也證明瞭List[A]是個free monoid。我們再看看free monad結構Free的定義:scalaz/Free.scala 我們在上
  • 本篇分為兩部分: 一、Swift中的方法嵌套 二、Swift中的命名空間 在 swift 中我們可以讓方法嵌套方法,如: 我們之前在使用 OC 開發時,它是沒有命名空間的,所有的代碼和引用的靜態庫最終都會被編譯到同一個域和二進位中,這樣的後果是一旦我們有重覆的類名的話,就會導致編譯時的衝突和失敗。為
  • 表達式樹: 葉子是操作數,其餘結點為操作符,是二叉樹的其中一種應用 我是分割線 一棵表達式樹如下圖: 若是對它做中序遍歷,則可以得到中綴表達式 做後序遍歷,則可以得到尾碼表達式 已知樹的結點可以表示成: 用尾碼表達式構建一棵表達式樹: 思路:(與尾碼表達式計算四則運算結構相似) 1. 一一讀入輸入字
  • & 160;& 160;& 160;& 160; "上一篇隨筆" 介紹瞭如何使用Gradle內建任務,介紹了自定義Gradle任務類的三種方法(build文件,buildSrc文件夾、新建groovy項目),一個任務是一個原子操作,即不可分割的。項目開發過程中,我們往往需要按照一定順序執行多個任務以
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...