簡體   English   中英

為什么Java需要Serializable接口?

[英]Why Java needs Serializable interface?

我們需要大量的序列化工作,並且在使用的每個對象上必須指定Serializable標簽是一種負擔。 特別是當它是第三方類時,我們無法真正更改。

問題是:由於Serializable是一個空接口,並且一旦添加了implements Serializable ,Java便提供了強大的序列implements Serializable -為什么它們不使所有內容都可序列化,僅此而已?

我想念什么?

序列化充滿陷阱。 這種形式的自動序列化支持使類內部成為公共API的一部分(這就是javadoc為您提供類持久形式的原因 )。

為了實現長期持久性,類必須能夠解碼這種形式,這限制了您可以對類設計進行的更改。 這破壞了封裝。

序列化也可能導致安全問題。 通過能夠序列化其引用的任何對象,類可以訪問它通常無法訪問的數據(通過解析結果字節數據)。

還有其他問題,例如內部類的序列化形式定義不正確。

使所有類都可序列化將加劇這些問題。 請查看有效的Java第二版 ,特別是項目74:明智地實現可序列化

我認為Java和.Net人士這次都錯了,最好將所有內容默認設置為可序列化,而只需標記那些不能安全地序列化的類即可。

例如,在Smalltalk(70年代創建的語言)中,每個對象默認情況下都可以序列化。 考慮到絕大多數對象都可以安全地序列化,而只有少數對象不是,因此我不知道Java中為什么不是這種情況。

將對象標記為可序列化(帶有接口)並不能使該對象可序列化, 它一直都是可序列化的,只是現在您表達了一些系統可以自己發現的東西,所以我認為沒有真正的理由序列化就是現在的樣子。

我認為這要么是設計人員做出的錯誤決定,要么是事后才想到序列化,或者默認情況下該平台從未准備好安全,一致地對所有對象進行序列化。

並非所有內容都是真正可序列化的。 以網絡套接字連接為例。 您可以序列化套接字對象的數據/狀態,但是活動連接的本質將丟失。

默認情況下,Java中Serializable的主要作用是實際上使所有其他對象不可序列化。 序列化是一種非常危險的機制,尤其是在其默認實現中。 因此,就像C ++中的友誼一樣,即使使事情可序列化花費一點時間,默認情況下它也處於關閉狀態。

序列化增加了約束和潛在的問題,因為沒有保證結構的兼容性。 最好默認將其關閉。

我必須承認,我看到過很少的非平凡類,其中標准序列化可以實現我想要的功能。 特別是在復雜的數據結構的情況下。 因此,您花在使類可序列化上的努力使添加接口的成本相形見war。

對於某些類,尤其是那些表示更物理類的類,例如文件,套接字,線程或數據庫連接,序列化實例絕對沒有意義。 對於許多其他人,序列化可能會帶來問題,因為序列化會破壞唯一性約束,或者只是迫使您處理類的不同版本的實例,而這可能是您不希望的。

可以說,最好將所有內容默認設置為可序列化,並通過關鍵字或標記接口使類不可序列化-但是,那些應該使用該選項的人可能不會考慮。 它的方式是,如果您需要實現Serializable,則會通過Exception告知您。

我認為盡管如此是為了確保您作為程序員知道您的對象可以序列化。

顯然,在某些初步設計中,所有內容都可以序列化,但由於安全性和正確性,最終設計最終眾所周知。

資料來源: 為什么類必須實現序列化才能寫入ObjectOutputStream?

閱讀此書以了解Serializable接口以及為什么我們只應使幾個類可序列化,並且在要從存儲過程中刪除一些字段的情況下,我們也應注意在哪里使用transient關鍵字。

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/

必須明確聲明某個類的實例是可序列化的,因此該語言迫使您考慮是否應該允許這樣做。 對於簡單的值對象,序列化是微不足道的,但是在更復雜的情況下,您需要認真考慮。

僅依靠JVM的標准序列化支持,您就可以面對各種討厭的版本控制問題。

唯一性,對“實際”資源的引用,計時器和許多其他類型的工件都不適合序列化。

Java中有些東西根本無法序列化,因為它們是運行時特定的。 流,線程,運行時等內容,甚至某些GUI類(連接至底層OS)都無法序列化。

盡管我在這里同意其他答案的觀點,但真正的問題在於反序列化:如果類定義發生更改,則存在真正的風險,即反序列化將無法進行。 對於圖書館作者來說,絕不修改現有字段是一項重大的承諾! 保持API兼容性就足夠了。

需要持久化到文件或其他媒體上的類必須實現Serializable接口,以便JVM可以允許對類對象進行序列化。 為什么不對Object類進行序列化,那么所有類都不需要實現接口,畢竟只有當我使用ObjectOutputStream時,所有JVM才會對類進行序列化,這意味着控件仍在我手中,可以讓JVM進行序列化。

對象類默認情況下無法序列化的原因是該類版本是主要問題。 因此,每個對序列化感興趣的類都必須顯式標記為Serializable並提供版本號serialVersionUID。

如果未提供serialVersionUID,則在反序列化對象時會得到意外的結果,這就是為什么如果serialVersionUID不匹配,JVM會拋出InvalidClassException的原因。 因此,每個類都必須實現Serializable接口並提供serialVersionUID ,以確保兩端顯示的類相同。

好吧,我的回答是,這沒有充分的理由。 從您的評論中,我可以看到您已經了解了這一點。 其他語言愉快地嘗試對數到10之后沒有跳到樹上的所有內容進行序列化。對象應默認可序列化。

因此,您基本上需要做的是自己閱讀3rd-party類的所有屬性。 或者,如果這是您的選擇,請執行以下操作:反編譯,將該死的關鍵字放在此處,然后重新編譯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM