欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java對象序列化總結

在網(wǎng)上看了很多有關(guān)序列化的文章,我自己也寫(xiě)了兩篇,現在感覺(jué)這些文章都沒(méi)有很好的把序列化說(shuō)清楚(包括我自己在內),所以在此我將總結前人以及自己的經(jīng)驗,用更淺顯易懂的語(yǔ)言來(lái)描述該機制,當然,仍然會(huì )有不好的地方,希望你看后可以指出,作為一名程序員應該具有不斷探索的精神和強烈的求知欲望!

序列化概述:

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

問(wèn)題的引出:

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

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

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

2.當要保存一個(gè)對象時(shí),先檢查該對象是否被保存了。

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

通過(guò)以上的步驟序列化機制解決了對象引用的問(wèn)題!

序列化的實(shí)現:

     將需要被序列化的類(lèi)實(shí)現Serializable接口,該接口沒(méi)有需要實(shí)現的方法,implementsSerializable只是為了標注該對象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來(lái)構造一個(gè)ObjectOutputStream(對象流)對象,接著(zhù),使用ObjectOutputStream對象的writeObject(Objectobj)方法就可以將參數為obj的對象寫(xiě)出(即保存其狀態(tài)),要恢復的話(huà)則用輸入流。

例子:

import java.io.*;

public class Test
{
    public static void main(String[] args)
    {
        Employee harry = new Employee("Harry Hacker", 50000);
        Manager manager1 = new Manager("Tony Tester", 80000);
        manager1.setSecretary(harry);
       
        Employee[] staff = new Employee[2];
       
        staff[0] = harry;
        staff[1] = manager1;
        try
        {
            ObjectOutputStream out = new ObjectOutputStream(
                new FileOutputStream("employee.dat"));
            out.writeObject(staff);
            out.close();
           
            ObjectInputStream in = new ObjectInputStream(
                new FileInputStream("employee.dat"));
            Employee[] newStaff = (Employee[])in.readObject();
            in.close();
  
            /**
             *通過(guò)harry對象來(lái)加薪
             *將在secretary上反映出來(lái)
             */
            newStaff[0].raiseSalary(10);
           
            for (int i = 0; i < newStaff.length; i++)
                System.out.println(newStaff[i]);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
   
}

class Employee implements Serializable
{
    public Employee(String n, double s)
    {
        name = n;
        salary = s;
    }
   
    /**
     *加薪水
     */
    public void raiseSalary(double byPercent)
    {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
   
    public String toString()
    {
        return getClass().getName()
            + "[name = "+ name
            + ",salary = "+ salary
            + "]";
    }
   
    private String name;
    private double salary;
}

class Manager extends Employee
{
    public Manager(String n, double s)
    {
        super(n, s);
        secretary = null;
    }
   
    /**
     *設置秘書(shū)
     */
    public void setSecretary(Employee s)
    {
        secretary = s;
    }
   
    public String toString()
    {
        return super.toString()
            + "[secretary = "+ secretary
            + "]";
    }
   
    //secretary代表秘書(shū)
    private Employee secretary; 
}

修改默認的序列化機制:   

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

private void readObject(ObjectInputStream in) IOException, ClassNotFoundException;

private void writeObject(ObjectOutputStream out) IOException;

(注:這些方法定義時(shí)必須是私有的,因為不需要你顯示調用,序列化機制會(huì )自動(dòng)調用的)

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

      下面是一個(gè)典型的例子,java.awt.geom包中的Point2D.Double類(lèi)就是不可序列化的,因為該類(lèi)沒(méi)有實(shí)現Serializable接口,在我的例子中將把它當作LabeledPoint類(lèi)中的一個(gè)數據字段,并演示如何將其序列化!

import java.io.*;
import java.awt.geom.*;

public class TransientTest
{
    public static void main(String[] args)
    {
        LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00);
        try
        {
            System.out.println(label);//寫(xiě)入前
            ObjectOutputStream out = new ObjectOutputStream(new
                FileOutputStream("Label.txt"));
            out.writeObject(label);
            out.close();
           
            System.out.println(label);//寫(xiě)入后
           
            ObjectInputStream in = new ObjectInputStream(new
                FileInputStream("Label.txt"));
            LabeledPoint label1 = (LabeledPoint)in.readObject();
            in.close();
            System.out.println(label1);//讀出并加1.0后
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
   
}

class LabeledPoint implements Serializable
{
    public LabeledPoint(String str, double x, double y)
    {
        label = str;
        point = new Point2D.Double(x, y);
    }
   
    private void writeObject(ObjectOutputStream out) throws IOException
    {
        /**
         *必須通過(guò)調用defaultWriteObject()方法來(lái)寫(xiě)入
         *對象的描述以及那些可以被序列化的字段
         */
        out.defaultWriteObject();
        out.writeDouble(point.getX());
        out.writeDouble(point.getY());
    }
   
    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        /**
         *必須調用defaultReadObject()方法
         */
        in.defaultReadObject();
        double x = in.readDouble() + 1.0;
        double y = in.readDouble() + 1.0;
        point = new Point2D.Double(x, y);
    }
   
    public String toString()
    {
        return getClass().getName()
            + "[label = "+ label
            + ", point.getX() = "+ point.getX()
            + ", point.getY() = "+ point.getY()
            + "]";
    }
   
    private  String label;
    transient private Point2D.Double point;
}

補充:

1. java.beans.XMLEncoder, 可簡(jiǎn)單地將bean對象直接轉換為XML串/流;

   java.beans.XMLDecoder, 實(shí)現上述的逆操作;

   優(yōu)點(diǎn):內置于JDK中,無(wú)需額外的包;

         支持通用集合類(lèi)(List,Set,Map...);

         使用簡(jiǎn)便;

   缺點(diǎn):若要轉換的bean中有String屬性,且字符串為漢字時(shí), 轉換后可能出現格式錯誤, 此時(shí)無(wú)法恢復成bean對象;

         (查看了源碼,發(fā)現轉換串時(shí)默認編碼格式為UTF-8,且此默認值為private static,無(wú)法由外部調用來(lái)修改)

2. XStream, 開(kāi)源庫,實(shí)現類(lèi)似上述的操作;(http://xstream.codehaus.org/index.html)


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
java serializable 序列化概述
通過(guò)socket連接傳遞java對象(對象序列化)
JAVA對象序列化機制
序列化與克隆
Java序列化與反序列化
java序列化實(shí)現Serializable接口
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久