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對象包裹起來.....詳細見裝飾模式一章.

你可能感兴趣的:(Java世界)