JavaBeans入門’(その2)
前回は、JavaBeansを実現する技術として、Javaのreflection機能を説明した。再度、JavaBeansの機能をまとめておくと、
1.
Builderのデザインシートの上に、お絵描きソフトの感覚でクラスを張り付けることができる。つまり、Builderというツールが(外部の)Beansを操作することができる。
2.
属性(プロパティ)をプロパティシートに羅列された個々のプロパティエディタ上で変更し、保存できる。つまり、ロードしたBeansの状態を変更することができる。
3.
2つのクラスに対して特定の「イベントオブジェクト」の交換を指定することで連携させることができる。
4.
デザインシートごと保存して、実行可能なJavaプログラムとすることができる。
reflectionの機能は、1,2の機能を実現するために使われている。Beansは、JavaBeansの仕様で記述されたクラス(ファイル)である。基本的にはどのクラスファイルでもBeansとして扱うことができるが、JavaBeansの仕様で書いておくことによって、Builderで内部の値を変更できるようになる。これを行うのがJava Beansのintrospection機能である。これは、reflection機能を使って実装されており、高レベルのreflection機能と言える。
JavaBeans = Properties
+ EventSets + Methods
JavaBeansは、JavaBeansの仕様に従ったクラスオブジェクトである。JavaBeansにある属性を持たせるには、JavaBeansの仕様に従ったメソッドを定義する。クラスの属性は大体はクラスのフィールド(インスタンス変数)で実現されることが多いのであるが、その属性をアクセスするメソッドの名前で決める。たとえば、あるBeansがforegroundという名前のプロパティも持つのは、そのbeansがColor getForegroud()とvoid setForegroud(Color c)というメソッドを持つ場合である。プロパティをセットするメソッドをsetter、取り出すメソッドをgetterという。あるプロパティに対し、
setter= “set” + プロパティ名 getter = “get” + プロパティ名
となる。通常プロパティ名は小文字になるが、1文字目と2文字目が両方とも大文字だったら、プロパティ名はそのままの名前を使うことに注意。
また、booleanプロパティの場合には、getterの名前は、”is”から始まる。
たとえば、
public class
oneProp {
private
int p = 9;
public
int getProp() { return p; }
public
int setProp(int i) { p = i; }
}
では、propという属性を持つbeanになる。
プロパティが変化した場合に、他のbeansに伝える機能PropertyChangeSupportクラスや、プロパティを変化させるPropertyEditor のクラスを指定する機能があるが、省略する。
さて、JavaBeansでもお互いのイベントを交換するために、AWTで解説したEvent Listenerモデルを使っている。これは、イベント発生する側にどこにそのイベントを伝えるかを設定し、イベントが伝えられる側にリスナーメソッドを定義するものである。あるJavaBeansがfoo という名前のイベントを発生するとする。このとき、beansはイベントセットfooを持つという。このbeansはfooEventというイベントオブジェクトの送り手とならなくてはならない。すなわち、このbeansにこのイベントの受け手であるFooListenerを登録することができるメソッドaddFooListenerがあることを意味する。javaBeansでは、プロパティと同様に規則的な名前をつけることによって、定義する。
Eventオブジェクト class “イベント”Event extends java.util.EventObject
Listener
interface “イベント”Listener extends
java.util.EventListener
Listerner登録 void add”イベント”Listener(“イベント”Listener listener)
Listerner抹消 void remove”イベント”Listener(“イベント”Listener listener)
たとえば、次の例では一つのイベントセットfooをもつbeansである。
import
java.util.*;
public
interface FooListener extends { … }
import
java.beans.*;
public class
eventDesc {
public void addFooListener(FooListener
l){ … }
public void
removeFooListener(FooListener l) { … }
}
JavaBeansでは、プロパティと同様に、このような名前の規則に従ったメソッドを探すことによって、イベントセットを見つける。
さて、Builderでは以上にみるようなプロパティやイベントセット、メソッドを持っているかを調べて、それらを操作する。このような性質を調べる機能がintrospectionである。intropsectorクラスを用いることによって調べることができるようになっている。
import
java.beans.intropsector;
….
Beans Info = Intropsector.getBeanInfo(Class beanClass);
添付したソースプログラムは、この機能を利用してプロパティを調べるプログラムである。
Serialization
JavaBeansの全体像を明らかにする前に、Javaの重要な機能であるSerializationについて述べる。この機能は、オブジェクトの状態をファイルやネットワーク上に書き出したり、読み込み復元したりする機能である。次の例は、Dateというオブジェクトをファイルに書き出す例である。
Date d = new
Date(); ….
FileOutputStream
fout = new FileOutputStream(“tmp”);
ObjectOutputStream
out = new ObjectOutputStream(fout);
out.write(d);
out.flush();
このファイルから、呼び出してオブジェクトを復元するには、
FileInputStream
fin = new FileInputStream(“tmp”);
ObjectInputStream
in = new ObjectInputStream(in);
Date d =
(Date)in.readObject();
一つ注意することは、すべてのオブジェクトがwriteObjectで書き出すことができるわけではないことである。このように書き出すことのできるオブジェクトは、Serializableインタフェースを実装していなくてはならない。これをやるには単に、Serializableインタフェースをつければよい。
import
java.io.Serializable;
public class
myClass implements Serializable { … }
この機能は、Builderでいろいろな属性を変更したオブジェクトの状態をファイルにセーブし、プログラムの実行時に設定の状態を復元するのに用いられている。Seralizationでは、オブジェクト(つまりインスタンス)を転送している。例では、Dateというクラスがすでにプログラムにあるが、未知のクラスのオブジェクトを復元するためにはそのクラスをロードしておかなくてはならない。
この機能はネットワークごしに他のマシンに任意のデータを転送したりする場合にも用いられている機能であり、Javaの分散環境であるJiniやRMIでは重要な役割を果たす。
次回は、JavaBeansのbeansを結びすける(Wiring)とアプレットの生成について解説する。
次回は、5月23日(5月16日は休講)