溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java的Serializable接口怎么使用

發(fā)布時(shí)間:2021-11-24 16:24:10 來(lái)源:億速云 閱讀:465 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹“Java的Serializable接口怎么使用”,在日常操作中,相信很多人在Java的Serializable接口怎么使用問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Java的Serializable接口怎么使用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

一、Serializable:序列化

1、Serializable位于java.io包中,用于實(shí)現(xiàn)Java類(lèi)的序列化操作而提供的一個(gè)語(yǔ)義級(jí)別的接口。沒(méi)有任何方法或者字段,只是用于標(biāo)識(shí)可序列化的語(yǔ)義。

2、如類(lèi)中的有些字段不想序列化,可用關(guān)鍵字:transient修飾。

3、序列化可通過(guò)ObjectOutputStream實(shí)現(xiàn),反序列化可通過(guò)ObjectInputStream實(shí)現(xiàn)。

4、自定義序列化實(shí)現(xiàn)接口:Externalizable

5、序列化作用:用于網(wǎng)絡(luò)傳輸(RPC遠(yuǎn)程調(diào)用); 將對(duì)象保存到磁盤(pán)(tomcat的鈍化和活化)

6、使用建議:實(shí)現(xiàn)序列化接口,請(qǐng)?jiān)黾樱?/p>

private static final long serialVersionUID = 1L;

7、可直接通過(guò)序列化字節(jié)流使用

// 將對(duì)象本身序列化到字節(jié)流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

ObjectOutputStream objectOutputStream =

new ObjectOutputStream( byteArrayOutputStream );

objectOutputStream.writeObject( this );

// 再將字節(jié)流通過(guò)反序列化方式得到對(duì)象副本
ObjectInputStream objectInputStream =

new ObjectInputStream( new ByteArrayInputStream( byteArrayOutputStream.toByteArray() ) );

Object object = objectInputStream.readObject();

8、可通過(guò)java命令:serialver [-classpath classpath] [-show] [classname...] 查看類(lèi)的序列化值

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打開(kāi)cmd輸入以下命令:

serialver -classpath E:\j2se-example\target\classes net.liuzd.j2se.example.copy.MyDong

Java的Serializable接口怎么使用

二、例子

1、測(cè)試類(lèi)

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("楊過(guò)");

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 運(yùn)行后,成功打印出結(jié)果: Dong{name='楊過(guò)', age=19}

2、測(cè)試類(lèi)再增加一個(gè)屬性

2.1 測(cè)試類(lèi)再增加一個(gè)屬性:sex及對(duì)應(yīng)的get,set方法,重寫(xiě)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 直接運(yùn)行方法:

ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName));

Dong readDong = (Dong) inputStream.readObject();

System.out.println(readDong);

2.3 發(fā)現(xiàn)報(bào)錯(cuò)了:

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 發(fā)現(xiàn)問(wèn)題:

2.4.1、我們沒(méi)有指定serialVersionUID,JDK8自動(dòng)幫我們生成了一個(gè)

2.4.2、發(fā)現(xiàn)二個(gè)serialVersionUID不一致,才導(dǎo)致了運(yùn)行錯(cuò)誤。

2.5 查看接口:serializable的文檔

2.5.1 明確指出需要我們顯式聲明為:private static final long serialVersionUID,這個(gè)對(duì)繼承成員無(wú)用。

2.5.2 默認(rèn)的serialVersionUID值對(duì)類(lèi)細(xì)節(jié)高度敏感,這些細(xì)節(jié)可能因編譯器而異實(shí)現(xiàn),并因此可能導(dǎo)致意外的結(jié)果:InvalidClassException

2.5.3 其中的一段文檔注釋?zhuān)?/p>

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 實(shí)踐

2.6.1 只增加serialVersionUID屬性

如果我們只在1.1中指定serialVersionUID,再試一次,結(jié)果會(huì)怎么樣?(沒(méi)有增加sex喲)

操作步驟:我們?cè)?.1中的類(lèi): Dog 增加serialVersionUID屬性。

private static final long serialVersionUID = 1L;

再次運(yùn)行結(jié)果:如1.2所示。

2.6.2 重復(fù)第2.1步驟喲,其它不變喲。

2.6.3 重復(fù)第2.2步驟,運(yùn)行結(jié)果:正確 !

Dong{name='楊過(guò)', age=19, sex=0}

到此,關(guān)于“Java的Serializable接口怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI