<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 51, comments - 17, trackbacks - 0, articles - 9
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java serializable

    Posted on 2007-03-09 20:13 chenweicai 閱讀(378) 評論(0)  編輯  收藏

    序列化概述

    簡單來說序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內(nèi)容進(jìn)行流化,流的概念這里不用多說(就是I/O),我們可以對流化后的對象進(jìn)行讀寫操作,也可將流化后的對象傳輸于網(wǎng)絡(luò)之間(注:要想將對象傳輸于網(wǎng)絡(luò)必須進(jìn)行流化)!在對對象流進(jìn)行讀寫操作時會引發(fā)一些問題,而序列化機制正是用來解決這些問題的!

    問題的引出:

    如上所述,讀寫對象會有什么問題呢?比如:我要將對象寫入一個磁盤文件而后再將其讀出來會有什么問題嗎?別急,其中一個最大的問題就是對象引用!舉個例子來說:假如我有兩個類,分別是A和B,B類中含有一個指向A類對象的引用,現(xiàn)在我們對兩個類進(jìn)行實例化{ A a = new A(); B b = new B(); },這時在內(nèi)存中實際上分配了兩個空間,一個存儲對象a,一個存儲對象b,接下來我們想將它們寫入到磁盤的一個文件中去,就在寫入文件時出現(xiàn)了問題!因為對象b包含對對象a的引用,所以系統(tǒng)會自動的將a的數(shù)據(jù)復(fù)制一份到b中,這樣的話當(dāng)我們從文件中恢復(fù)對象時(也就是重新加載到內(nèi)存中)時,內(nèi)存分配了三個空間,而對象a同時在內(nèi)存中存在兩份,想一想后果吧,如果我想修改對象a的數(shù)據(jù)的話,那不是還要搜索它的每一份拷貝來達(dá)到對象數(shù)據(jù)的一致性,這不是我們所希望的!

    以下序列化機制的解決方案:

    1.保存到磁盤的所有對象都獲得一個序列號(1, 2, 3等等)

    2.當(dāng)要保存一個對象時,先檢查該對象是否被保存了。

    3.如果以前保存過,只需寫入"與已經(jīng)保存的具有序列號x的對象相同"的標(biāo)記,否則,保存該對象

    通過以上的步驟序列化機制解決了對象引用的問題!

    序列化的實現(xiàn)

    將需要被序列化的類實現(xiàn)Serializable接口,該接口沒有需要實現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構(gòu)造一個ObjectOutputStream(對象流)對象,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以將參數(shù)為obj的對象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。
    package serializable;

    import java.io.Serializable;

    public class Employee implements Serializable {

    ?private String name;
    ?
    ?private double salary;

    ?public Employee(String name, double salary) {
    ??super();
    ??// TODO Auto-generated constructor stub
    ??this.name = name;
    ??this.salary = salary;
    ?}
    ?
    ?public void raiseSalary(double byPercent){
    ??double temp = salary * byPercent / 100;
    ??salary += temp;
    ?}

    ?public String toString() {
    ??// TODO Auto-generated method stub
    ??return getClass().getName() +
    ???"[ Name = " + name + ", salary = " + salary +"]";
    ?}

    package serializable;

    public class Manager extends Employee {
    ?
    ?private Employee secretary;

    ?public Manager(String name, double salary) {
    ??super(name, salary);
    ??// TODO Auto-generated constructor stub
    ??secretary = null;
    ?}

    ?public Employee getSecretary() {
    ??return secretary;
    ?}

    ?public void setSecretary(Employee secretary) {
    ??this.secretary = secretary;
    ?}

    ?public String toString() {
    ??// TODO Auto-generated method stub
    ??return super.toString() + "[ secretary = " + secretary +"]";
    ?}
    ?
    }

    package serializable;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;

    public class Test {
    ?
    ?public static void main(String[] args){
    ??
    ??Employee employee = new Employee("LiLei", 1000);
    ??Manager manager1 = new Manager("Jim", 20000);
    ??manager1.setSecretary(employee);
    ??
    ??Employee[] staff = new Employee[2];
    ??staff[0] = employee;
    ??staff[1] = manager1;
    ??
    ??try{
    ???ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("employee.dat"));
    ???oos.writeObject(staff);
    ???oos.close();
    ???
    ???ObjectInputStream ois = new ObjectInputStream(new FileInputStream("employee.dat"));
    ???Employee[] newStaff = (Employee[])ois.readObject();
    ???ois.close();
    ???
    ???newStaff[0].raiseSalary(1000);
    ???
    ???for(int i=0; i<newStaff.length; i++)
    ????System.out.println(newStaff[i]);
    ???
    ??}catch(Exception e)
    ??{
    ???e.printStackTrace();
    ??}
    ?}
    }

    修改默認(rèn)的序列化機制?

    在序列化的過程中,有些數(shù)據(jù)字段我們不想將其序列化,對于此類字段我們只需要在定義時給它加上transient關(guān)鍵字即可,對于transient字段序列化機制會跳過不會將其寫入文件,當(dāng)然也不可被恢復(fù)。但有時我們想將某一字段序列化,但它在SDK中的定義卻是不可序列化的類型,這樣的話我們也必須把他標(biāo)注為transient,可是不能寫入又怎么恢復(fù)呢?好在序列化機制為包含這種特殊問題的類提供了如下的方法定義:

    private?void readObject(ObjectInputStream in) throws

    IOException, ClassNotFoundException;

    private void writeObject(ObjectOutputStream out) throws

    IOException;

    (注:這些方法定義時必須是私有的,因為不需要你顯示調(diào)用,序列化機制會自動調(diào)用的)

    使用以上方法我們可以手動對那些你又想序列化又不可以被序列化的數(shù)據(jù)字段進(jìn)行寫出和讀入操作。

    下面是一個典型的例子,java.awt.geom包中的Point2D.Double類就是不可序列化的,因為該類沒有實現(xiàn)Serializable接口,在我的例子中將把它當(dāng)作LabeledPoint類中的一個數(shù)據(jù)字段,并演示如何將其序列化
    package transientTest;

    import java.awt.geom.Point2D;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;


    public class LabeledPoint implements Serializable {

    ?private String label;
    ?transient private Point2D.Double point;
    ?
    ?public LabeledPoint(String label, double x, double y) {
    ??super();
    ??// TODO Auto-generated constructor stub
    ??this.label = label;
    ??this.point = new Point2D.Double(x,y);
    ?}
    ?
    ?private void writeObject(ObjectOutputStream oos)throws IOException{
    ??
    ??oos.defaultWriteObject();
    ??oos.writeDouble(point.getX());
    ??oos.writeDouble(point.getY());
    ?}
    ?
    ?private void readObject(ObjectInputStream ois)throws IOException, ClassNotFoundException{
    ??
    ??ois.defaultReadObject();
    ??double x = ois.readDouble() + 1.0;
    ??double y = ois.readDouble() + 1.0;
    ??point = new Point2D.Double(x,y);
    ?}

    ?public String toString() {
    ??// TODO Auto-generated method stub
    ??return getClass().getName() + "[ Label = " + label + ", point.getX() = "
    ???+ point.getX() + ", point.getY() = " + point.getY() + "]";
    ?}
    }

    package transientTest;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;

    public class transientTest {

    ?public static void main(String[] args){
    ??LabeledPoint label = new LabeledPoint("Book", 5.0, 5.0);
    ??
    ??try{
    ???System.out.println("before:\n" + label);
    ???
    ???ObjectOutputStream oos = new ObjectOutputStream(
    ?????new FileOutputStream("c:\\label.txt"));
    ???oos.writeObject(label);
    ???oos.close();
    ???
    ???System.out.println("after:\n" + label);
    ???ObjectInputStream ois = new ObjectInputStream(
    ?????new FileInputStream("c:\\label.txt"));
    ???LabeledPoint label1 = (LabeledPoint)ois.readObject();
    ???ois.close();
    ???
    ???System.out.println("after add 1.0:\n" + label);
    ??}catch(Exception e)
    ??{
    ???e.printStackTrace();
    ??}
    ?}
    }


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲AV无码精品国产成人| 免费高清av一区二区三区| 亚洲国产成人AV网站| 亚洲精品在线播放视频| 亚洲一区二区三区影院| 无码国模国产在线观看免费| 最近最新高清免费中文字幕| 日韩免费高清播放器| 黄色网址大全免费| 亚洲AV一区二区三区四区| 亚洲欧洲春色校园另类小说| 久久国产亚洲电影天堂| 区久久AAA片69亚洲| 亚洲国产成人五月综合网| 日韩免费观看视频| 成人免费午间影院在线观看| 99久久国产热无码精品免费 | 在线免费观看中文字幕| aⅴ在线免费观看| 免费国产污网站在线观看15| a在线观看免费网址大全| 国产精品美女久久久免费| 日韩在线观看免费| 男女交性无遮挡免费视频| 另类专区另类专区亚洲| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲中文字幕日产乱码高清app| 日韩国产免费一区二区三区| 美女内射无套日韩免费播放 | 国产午夜亚洲不卡| 亚洲国产小视频精品久久久三级| 日韩毛片无码永久免费看| 在线jlzzjlzz免费播放| 女人被男人躁的女爽免费视频| 成人免费福利电影| 成人免费视频国产| 免费国产真实迷j在线观看| 免费一看一级毛片人| 亚洲精品国产精品乱码不卡| 亚洲精品无码久久久| 国产成人亚洲综合|