国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java - Serializable (2)

2019-11-17 04:09:26
字體:
來源:轉載
供稿:網友
from: -http://www.cjsdn.net/post/view?bid=2&id=192312&sty=1&tpg=5&age=0

一、序列化簡介
在這里我先簡要介紹一下和序列化相關的一些概念,如果你覺得自己對序列化已經比較熟悉,那么跳過這一節,直接看下一節內容。
序列化是java中的一個非常重要的特性,通過序列化機制,我們可以將Java的對象變成流,或者存儲在硬盤中,或者通過網絡傳輸給網絡的其他用戶。而序列化在RMI,EJB中都有應用,可以說是構成J2EE的一個重要的技術。
1)Serializable接口
如果想讓一個類可被序列化,那么這個類必須實現Serializable接口,這個接口本身沒有任何方法和屬性,它的作用只是為了標示一個類可以被序列化,這一個特性好像在Java里用的比較多,比如克隆也是采用了相同的機制。
因此,如果我們想創建一個可以被序列化的類,我們可以像下面的代碼一樣做。
import java.io.Serializable;
public class SerialClass implements Serializable
{
PRivate static final long serialVersionUID = -190734710746841476L;
private String c;
public int a;
public String b;

public int getA(){return a;}
public String getB(){return b;}
public void setA(int a){this.a = a;}
public void setB(String b){this.b = b;}
public String getC(){return c; }
public void setC(String c){this.c = c; }
  從上面的例子我們可以看到,除了需要實現Serialzable接口外,一個可序列化的類和一個普通類沒有什么大的區別。不過我們還是有一些特別的東西需要注意的。
2)屬性 serialVersionUID
這個屬性是一個私有的靜態final屬性,一般剛接觸序列化的人會忽略這個屬性,因為這個屬性不是必須的。這個屬性主要是為了保證一個可序列化類在不同的Java編譯器中,能保證相同的版本號,這樣保證當這個類在不同的JVM中進行序列化與反序列化時不會出現InvalidClassException異常。
3)屬性與序列化
那么我們再考慮另一個問題,是不是一個類實現了Serializable之后就可以看成是可序列化的類呢?答案是不行,實際上一個類是否可序列化還需要看這個類的屬性,在Java規范中,一個類是否能序列化,不但取決于這個類是否實現Serializable接口,還取決于這個類中的屬性是否可序列化。在上面的例子里,一共有三個屬性,兩個是String對象,一個是int類型的屬性,實際上,String類是可序列化的(繼承了Serializable接口且它的屬性都是可序列化的),而像int這樣的基本數據類型在Java中被看成是可序列化的,因此我們可以確認上面的這個類是一個可序列化的類。那么現在我們已經創建了一個可序列化類,接下去的問題是怎么使用這個類,對它進行序列化與反序列化操作?
4)ObjectOutputStream 和 ObjectInputStream類
Jdk提供了兩個IO流類進行序列化和反序列化操作,其中ObjectOutputStream中的writeObject方法對一個對象進行序列化工作;而ObjectInputStrem中的readObject方法則負責發序列化的操作。下面的例子完整的顯示了一個類的序列化和反序列化操作。
package serialtest;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TestClass
{
public static void main(String[] args) throws Exception
{
SerialClass s = new SerialClass();
s.setA(10);
s.setB("hello");
s.setC("world");
//創建ObjectOutputStream對象,準備序列化對象s
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("abc"));
//調用writeObject將對象進行序列化,存儲在文件abc中。
oos.writeObject;
oos.flush();
oos.close();

//創建ObjectInputStream對象,準備從文件abc中反序列化SerialClass對象
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("abc"));
//調用readObject將存儲在文件abc中的字節流反序列化為SerialClass對象。
s = (SerialClass) ois.readObject();
System.out.println(s.getA());
System.out.println(s.getB());
System.out.println(s.getC());
}
}
執行程序,最后的結果應該是:
10
Hello
World
好了,序列化的基礎知識就講到這里。接下來我們看看繼承對于序列化的影響。

二、繼承對序列化的影響
我們現在把上面的例子做點變換,變成如下的形式。
1)首先創建一個Interface。
package serialtest;
public interface SuperInterface
{
public int getA();
public String getB();
public void setA(int a);
public void setB(String b);
}
2)創建一個抽象類實現SuperInterface接口,注意,這個類沒有實現Serializable接口。
package serialtest;
public abstract class AbsSuperClass implements SuperInterface
{
public int a;
public String b;
public int getA() {return a;}
public String getB(){return b; }
public void setA(int a) {this.a = a;}
public void setB(String b) {this.b = b;}
}
3)SerialClass類繼承了AbSuperClass,同時它也實現了Serializable接口。
package serialtest;
import java.io.Serializable;
 
public class SerialClass extends AbsSuperClass implements Serializable
{
private static final long serialVersionUID = -190734710746841476L;
private String c;
public String getC(){return c; }
public void setC(String c) {this.c = c;}
}
這時候我們在運行Test,將會發現結果和第一節的例子不一樣了,這時候結果將變成:
0
null
world
而導致這個結果的原因就在AbSuperClass上,因為AbSuperClass沒有實現Serializable接口,所以它不可被序列化;但SerialClass由于實現了Serializable接口而成為一個可序列化的類,這時候,屬性c因為是SerialClass的類所以c的值在序列化時將被保存,而屬性a和b是從AbSuperClass中繼承而來,他們因為AbSuperClass的緣故而導致了它們的值不能在序列化是被保存。
關于這一點,我在Java文檔中也得到了證實,在Java doc中明確指出,如果一個類繼承了一個非Serializable類時,如果想在序列化中保存父類的屬性,則需要實現額外的代碼顯式地存儲父類的屬性值。
最后再回到本文的初衷,誠然,這篇文章是以對象的序列化為主的,但最后我又要回到一個比較古老的話題上,那就是在軟件開發的時候,繼承到底該用到什么一種程度?畢竟,濫用繼承對整個系統的影響將是深遠的。
上一篇:JAVA annotation入門

下一篇:VB與JAVA交互

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 会昌县| 中山市| 唐山市| 九江县| 南靖县| 台北市| 秦皇岛市| 阿尔山市| 泾源县| 南郑县| 芷江| 泽州县| 大丰市| 天台县| 从化市| 沂水县| 西昌市| 吉首市| 平乡县| 郯城县| 莎车县| 乐清市| 长岛县| 巴林左旗| 任丘市| 伊金霍洛旗| 甘泉县| 泾川县| 格尔木市| 德清县| 镶黄旗| 军事| 平昌县| 阳山县| 怀化市| 安庆市| 普兰店市| 莱西市| 屯门区| 资溪县| 高雄市|