天天看點

java對象序列化的概念和實作

一 序列化的概念和實作方法

序列化的概念就是把一個object直接轉換成為byte流寫到硬碟或者通過網絡進行傳播。java序列化技術可以将一個對象的狀态寫入一個byte流裡,并且可以從其它地方把該byte流裡的資料讀出來,重新構造一個相同的對象。這種機制允許将對象通過網絡進行傳播,并可以随時把對象持久化到資料庫、檔案等系統裡。java的序列化機制是rmi、ejb等技術的技術基礎。

序列化就是一種用來處理對象流的機制,所謂對象流也就是将對象的内容進行流化。可以對流化後的對象進行讀寫操作,也可将流化後的對象 傳輸于網絡之間。序列化是為了解決在對對象流進行讀寫操作時所引發的問題。

序列化的實作——将需要被序列化的類實作serializable接口,根據需求讀出或者寫入對象。在web開發中,如果對象被儲存在了session中,tomcat在重新開機時要把session對象序列化到硬碟,這個對象就必須實作serializable接口。如果對象要經過分布式系統進行網絡傳輸或通過rmi等遠端調用,這就需要在網絡上傳輸對象,被傳輸的對象就必須實作serializable接口。

看例子

import java.io.file;

import java.io.fileinputstream;

import java.io.fileoutputstream;

import java.io.ioexception;

import java.io.objectinputstream;

import java.io.objectoutputstream;

import java.io.serializable;

import java.net.urisyntaxexception;

import cn.test.fileinputandoutputstream;

public class objectio

{

 // 将對象寫入檔案

 public static void output(string path)

 {

  student s = new student();

  s.num = 2;

  s.name = "xy2";

  s.address = "goodplace2";

  s.wifename = "nobody2";

  file f = new file(path);

  fileoutputstream fout = null;

  objectoutputstream bout = null;

  try

  {

   fout = new fileoutputstream(f);

   bout = new objectoutputstream(fout);

   bout.writeobject(s);

   bout.flush();

   bout.close();

  }

  catch (ioexception e)

   e.printstacktrace();

 }

 // 将寫入的對象讀出

 public static void input(string path)

  fileinputstream fin = null;

  objectinputstream bin = null;

   fin = new fileinputstream(f);

   bin = new objectinputstream(fin);

   student s = (student) bin.readobject();

   system.out.println(s.num + "..." + s.name + "..." + s.address + "..." + s.wifename);

  catch (exception e)

 // writeobject和readobject是線程安全的,傳輸過程中不允許被并發通路,故對象能不斷傳來

 public static void main(string[] args) throws urisyntaxexception

  string path = fileinputandoutputstream.class.getclassloader().getresource("對象文檔.txt").touri().getpath();

  output(path);

  input(path);

}

@suppresswarnings("serial")

class student implements serializable

 int num = 1;

 string name = "xy";

 string address = "goodplace";

 transient string wifename = "nobody";

二 序列化的注意點

注意點1

如果某個類能夠被序列化,其子類也可以被序列化。如果該類有父類,則分兩種情況來考慮,如果該父類已經實作了可序列化接口。 則其父類的相應字段及屬性的處理和該類相同;如果該類的父類沒有實作可序列化接口,則該類的父類所有的字段屬性将不會序列化。

注意點2

聲明為static和transient類型的成員資料不能被序列化。因為static代表類的狀态,transient代表對象的臨時資料。

注意點3

在java.io包提供的涉及對象的序列化的類與接口有

objectoutput接口

該接口繼承dataoutput接口并支援對象的序列化,其writeobject()方法實作存儲一個對象。

objectinput接口

該接口繼承datainput接口并支援對象的序列化,其readobject()方法實作讀取一個對象。

objectoutputstream類

該類繼承outputstream類并實作objectoutput接口,可調用接口中的writeobject方法。

objectinputstream類。

該類繼承inputstream類并實作objectinput接口,可調用接口中的readobject方法。

注意點4

對于父類的處理時,若父類沒有實作序列化接口,則其必須有預設的構造函數,否則編譯的時候就會報錯。在反序列化的時候,預設構造函數會被調用。若把父類标記為可以序列化,則在反序列化的時候,其預設構造函數不會被調用。因為java對序列化的對象進行反序列化的時候,直接從流裡擷取其對象資料來生成一個對象執行個體,而不是通過其構造函數來完成。

參考部落格:http://blog.csdn.net/yakihappy/article/details/3979373