このドキュメントでは、Java SE 1.4でjava.beansパッケージに加えられた変更点について説明します。
長期的な持続性(long-term persistence)をサポートするために、次のようなクラスが追加されました。
| クラス | 説明 |
|---|---|
Statement |
オブジェクトのメソッド呼出しを表すオブジェクトで、引数を伴うことがある。 たとえば、a.setFoo(b)。 |
Expression |
結果を返す文。 たとえば、a.getFoo()。 |
XMLDecoder |
XMLEncoderを使って作成されたXMLドキュメントを読む。 |
Encoder |
持続性委譲を使って、オブジェクトのグラフを、それを再作成する際に使用できる一連のStatementとExpressionに分割する。 |
XMLEncoder |
XMLエンコーディングで文と式を生成するEncoder。 |
PersistenceDelegate |
そのオブジェクトのクラスのpublicメソッドを使用して、ほかのオブジェクトの状態を表すオブジェクトを定義する抽象クラス。 |
DefaultPersistenceDelegate |
Beanに対してデフォルトで使用する持続性委譲。 |
長期的な持続性に関する詳細情報についてのリンクは「JavaBeans Component API」を参照してください。
バージョン1.4では次のクラスも追加されました。
| クラス | 説明 |
|---|---|
EventHandler |
サイズが小さく、持続性スキームで自動的に保存されるイベント・リスナーの動的な生成をサポートする。 |
ExceptionListener |
例外がスローされたと通知されるが、その後そこから回復が行われるリスナーを定義する。 Beanの読書き中にオブジェクトが回復可能な問題に直面したときに通知する例外リスナーを、XMLEncoderまたはXMLDecoderオブジェクトに登録する。 |
PropertyChangeListenerProxy |
PropertyChangeListenerを実装し、固有のプロパティを使用してグループに別のPropertyChangeListener (実際のイベント・ハンドラ)を提供するプロキシ。プロキシはプロパティの変更イベントを実際のイベント・ハンドラに渡す。 |
VetoableChangeListenerProxy |
VetoableChangeListenerを実装し、固有の制約プロパティを使用してグループに別のVetoableChangeListener (実際のイベント・ハンドラ)を提供するプロキシ。プロキシは拒否可能なプロパティの変更イベントを実際のイベント・ハンドラに渡す。 |
次のクラスには追加メソッドがあります。
PropertyChangeSupportクラスには、登録されたプロパティ変更リスナーをすべて取得する、引数のないメソッドgetPropertyChangeListenersが含まれます。VetoableChangeSupportクラスには、登録された拒否可能な変更リスナーをすべて取得する、引数のないメソッドgetVetoableChangeListenersが含まれます。Introspectorクラスが再実装され、パフォーマンスが改善されました。 新しく実装されることで、Introspectorクラスの動作が次のように変更されました。
FeatureDescriptorは、BeanInfoが返されるときにコピーされるのではなく、BeanInfoごとに共有されるようになりました。 この変更により、getBeanInfoメソッドのパフォーマンスが向上します。 また、FeatureDescriptorの属性/値が変化すると、その変化は、BeanInfoがガベージ・コレクトされるまでgetBeanInfoの呼出しの間で持続します (BeanInfoのガベージ・コレクションについては、「ガベージ・コレクションとカスタム属性」を参照してください)。 getBeanInfoメソッドは、要求されたBeanInfoのコピーを作成しなくなりました。 代わりに、BeanInfoをキャッシュに保存してから返します。 必要であれば、返されたBeanInfoに参照を保存し、flushFromCachesメソッドでイントロスペクタのキャッシュからBeanのクラスをフラッシュして、以前の動作を得ることができます。 instantiateメソッドで、兄弟ウィジェットまたはブートストラップ・クラス・ローダーを使う特定のクラスをインスタンス化できない場合、現在のスレッドのクラス・ローダーを使うクラスをロードしようとします。v 1.4では、BeanInfoが直接参照されていない場合にシステムのメモリーが不足したときは、BeanInfoをガベージ・コレクトできます。 これは、BeanInfoをSoftReferenceにラップすることでIntrospectorに実装されています。
ガベージ・コレクトされる可能性があるため、BeanInfo内にカスタム属性を格納する方法も変わってきます。 特定のBeanInfoがガベージ・コレクトされた場合、次にIntrospector.getBeanInfoを呼び出してこのBeanInfoを取得するとき、返されるオブジェクトにカスタム属性が含まれなくなります。
この問題を避けるために、BeanInfo内にカスタム属性を格納する場合は、BeanInfoを取得するたびに、必ずこれらの属性を設定してBeanInfoを正しく初期化するようにしてください。 次のサンプル・コードは、Bean記述子のカスタム・プロパティを設定してBeanInfoクラスを初期化する方法を示しています。 プロパティ記述子、メソッド記述子、またはイベント・セット記述子のカスタム属性についても、このコードと同様になります。
BeanInfo beanInfo = getBeanInfo(SomeBean.class);
BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
/*
* Before using the BeanInfo, check to see if our custom
* property has been initialized. (Even if we initialized
* it before, if the BeanInfo has been garbage collected,
* then we need to initialize it again.) Since our custom
* property's value could be null, we define another property
* to tell us if the custom property is initialized.
*/
if (beanDescriptor.getValue("myProperty_init") == null) {
beanDescriptor.setValue("myProperty", someValue);
beanDescriptor.setValue("myProperty_init", Boolean.TRUE);
}