`

JavaBean的冷藏和解冻

阅读更多
本章主要講解怎么樣使用java.beans.Beans類對已經過串行化處理的JavaBean進行解凍處理,在本章會遇到工廠方法模式,標識接口模式和原始模型模式.

一:什么是冷藏和解凍
(1)串行化使得一個程序可以把一個完整的對象寫到一個Byte流里面,或者從一個Byte流里讀出一個事先存儲在里面的完整的對象:串行化可以把Java對象和原始數據類型轉換成一個適合於某種網絡或文件系統的Byte流.
(2)串行化處理的威力:串行處理功能真正強大之處在於一個Java程序不需要直接處理存儲在硬盤上面的原始數據,就可以很容易地將一個Java對象和一個二進制流之間相互轉換(要知道C從硬盤上讀取數據的麻煩,更不用說將二進制流轉換成所需要格式的各種細節的繁瑣),現在java把這些繁瑣都省去了,你只要實現Serializable接口(或它的子接口Externalizable)

二:什么類可以串行化
java.awt.Component實現了Serializable接口,因此所有Component直接的和間接的子類,包括Button,Scrollbar,TextArea,List,Container,Panel,java.applet.Applet以及所有的Applet的子類和Swing的子類,全都是可以串行化的,再比如java.lang.Throwable類也實現了Seralizable接口.因此所有的Exception,Error類均是可以串行化的。
一般而言,Exception,Error以及其他繼承自Throwable的類均是可以串行化的。而流,所有的Reader和Writer以及其他的I/O類均是不可能串行化的;AWT和Swing,容器類,事件類均是可以串行化的;事件適配器類,圖像過濾器類,AWT包中與操作系統相關的我類均是不可以串行化的;原始類型的封裝類中只有Void類是可以串行化的;多數的java.lang包中的類是不可以串行化的;反射(Reflection)類是不可以串行化的;java.math中的類都是可以串行化;壓縮類都是不可以串行化的.

三:什么樣的類不可以串行化
一般而言,滿足下面的四個條件之一的類就不應當串行化:
(1)一個類與本地代碼(native code)有緊密的關系,如java.util.zip.Deflater就是一個例子.
(2)對象的內部狀態依賴於java虛擬機或運行環境,從而每一次運行時這個狀態都有可能不同,比如java.lang.Thread,java.io.InkputStream,java.io.FileDescriptor,java.awt.PrintJob等。
(3)串行化可能帶潛在的安全隱患,比如java.lang.SecurityManager以及java.security.MessageDigest
(4)一個類僅僅是一些靜態方法的存放地,並沒有任何內部狀態,如java.beans.Beans和java.lang.Math

四:一個冷藏的例子
package cai.milenfan.basic.test;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.awt.TextField;

public class PickleMaker extends Frame{
 PickleMaker(String text,int size){
  super("Pickle Maker");
  //增加一個事件監聽器
  addWindowListener(new Win());
  setLayout(new FlowLayout());
  //創建TextField對象並將它串行化
  TextField textField = makeTextField(text,size);
  serializeTextField(textField,"c:\\mytextfield.ser");
  add(textField);
 }
 private TextField makeTextField(String text,int size){
  TextField textField = new TextField(text,size);
  return textField;
 }
 //串行化TextField
 private void serializeTextField(TextField textField,String filename){
  try {
   FileOutputStream outStream = new FileOutputStream(filename);
   ObjectOutputStream out = new ObjectOutputStream(outStream);
   out.writeObject(textField);
   out.flush();
   out.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 } 

//這個內部類提供監聽功能,以便在接到操作系統傳來的關閉窗口的事件時,將應用程序結束
 class Win extends WindowAdapter{
  public void windowClosing(WindowEvent evt){
   Frame frame = (Frame)evt.getSource();
   frame.setVisible(false);
   frame.disable();
   System.exit(0);
  }
 }
 
 public static void main(String[] args){
  Frame frame = new PickleMaker("No matter where you go,&this.",25);
  frame.setBounds(0, 0, 400, 300);
  frame.setVisible(true);
 } 
}
//在這個類的main()方法被調用時,會創建一個Frame對象,並顯示一個TextField對象,與此同時,這個TextField對象被串行化,
//存儲到名為mytextfield.ser的文件里(由於沒有指定路徑,這個文件會被放到包的根路徑上)


package cai.milenfan.basic.test;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.awt.TextField;
import java.beans.Beans;

public class ShowPickle extends Frame{
 ShowPickle(String serComponent){
  super("Show Pickle");
  addWindowListener(new Win());
  setLayout(new FlowLayout());
  
  TextField text;
  try{
   text = (TextField)Beans.instantiate(null, serComponent);
  }catch(Exception e){
   text = new TextField();
  }
  add(text);
 }
 class Win extends WindowAdapter{
  public void windowClosing(WindowEvent evt){
   Frame frame = (Frame)evt.getSource();
   frame.setVisible(false);
   frame.disable();
   System.exit(0);
  }
 } 
 public static void main(String[] args){
  Frame frame = new ShowPickle("c:/mytextfield");
  frame.pack();
  frame.setVisible(true);
 }
}

五:怎么樣在JSP中使用Beans.Instantiate方法.(略過)

六:與裝飾模式的關系
在使用串行化或者任何其他的I/O操作的時候,都不可以避免要使用裝飾模式:
ObjectOutputStream對象將FileOutputStream對象包裹起來.....詳細見裝飾模式一章.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics