您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java的Serializable接口怎么使用”,在日常操作中,相信很多人在Java的Serializable接口怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java的Serializable接口怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
一、Serializable:序列化
1、Serializable位于java.io包中,用于實現Java類的序列化操作而提供的一個語義級別的接口。沒有任何方法或者字段,只是用于標識可序列化的語義。
2、如類中的有些字段不想序列化,可用關鍵字:transient修飾。
3、序列化可通過ObjectOutputStream實現,反序列化可通過ObjectInputStream實現。
4、自定義序列化實現接口:Externalizable
5、序列化作用:用于網絡傳輸(RPC遠程調用); 將對象保存到磁盤(tomcat的鈍化和活化)
6、使用建議:實現序列化接口,請增加:
private static final long serialVersionUID = 1L;
7、可直接通過序列化字節流使用
// 將對象本身序列化到字節流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream( byteArrayOutputStream ); objectOutputStream.writeObject( this ); // 再將字節流通過反序列化方式得到對象副本 ObjectInputStream objectInputStream = new ObjectInputStream( new ByteArrayInputStream( byteArrayOutputStream.toByteArray() ) ); Object object = objectInputStream.readObject();
8、可通過java命令:serialver [-classpath classpath] [-show] [classname...] 查看類的序列化值
The -classpath option specifies where to look for the classes (in directories or jar files, separated by semicolon marks ;).
The -show option displays a simple user interface that allows the user to enter a full class name and then press Enter key or click Show button to display the serialVersionUID number.
示例:
//win+R打開cmd輸入以下命令: serialver -classpath E:\j2se-example\target\classes net.liuzd.j2se.example.copy.MyDong
二、例子
1、測試類
1.1 代碼示例
package net.liuzd.j2se.example.copy; import java.io.*; public class DongSerializableTest { static String fileName = "dong.ser"; public static void main(String[] args) throws Exception { Dong dong = new Dong(); dong.setName("楊過"); dong.setAge(19); // ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(fileName)); outputStream.writeObject(dong); outputStream.close(); // ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName)); Dong readDong = (Dong) inputStream.readObject(); System.out.println(readDong); } } class Dong implements Serializable { private String name; private int age; public Dong() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Dong{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
1.2 運行后,成功打印出結果: Dong{name='楊過', age=19}
2、測試類再增加一個屬性
2.1 測試類再增加一個屬性:sex及對應的get,set方法,重寫toString()方法。
private int sex; public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } @Override public String toString() { return "Dong{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; }
2.2 直接運行方法:
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName)); Dong readDong = (Dong) inputStream.readObject(); System.out.println(readDong);
2.3 發現報錯了:
Exception in thread "main" java.io.InvalidClassException: net.liuzd.j2se.example.copy.Dong; local class incompatible: stream classdesc serialVersionUID = 2001103299326914393, local class serialVersionUID = 1180199239641161346 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1963) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1829) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2120) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:482) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:440) at net.liuzd.j2se.example.copy.DongSerializableTest.main(DongSerializableTest.java:20)
2.4 發現問題:
2.4.1、我們沒有指定serialVersionUID,JDK8自動幫我們生成了一個
2.4.2、發現二個serialVersionUID不一致,才導致了運行錯誤。
2.5 查看接口:serializable的文檔
2.5.1 明確指出需要我們顯式聲明為:private static final long serialVersionUID,這個對繼承成員無用。
2.5.2 默認的serialVersionUID值對類細節高度敏感,這些細節可能因編譯器而異實現,并因此可能導致意外的結果:InvalidClassException
2.5.3 其中的一段文檔注釋:
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is <em>strongly recommended</em> that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected <code>InvalidClassException</code>s during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the <code>private</code> modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.
2.6 實踐
2.6.1 只增加serialVersionUID屬性
如果我們只在1.1中指定serialVersionUID,再試一次,結果會怎么樣?(沒有增加sex喲)
操作步驟:我們在1.1中的類: Dog 增加serialVersionUID屬性。
private static final long serialVersionUID = 1L;
再次運行結果:如1.2所示。
2.6.2 重復第2.1步驟喲,其它不變喲。
2.6.3 重復第2.2步驟,運行結果:正確 !
Dong{name='楊過', age=19, sex=0}
到此,關于“Java的Serializable接口怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。