This document describes changes to the java.beans package that were introduced in Java SE 1.4:
To support long-term persistence, the following classes were added:
Class | Description |
---|---|
Statement |
An object that represents a method call, possibly with
arguments, upon an object. For example:
a.setFoo(b) . |
Expression |
A statement that returns a result. For example:
a.getFoo() . |
XMLDecoder |
Reads XML documents that were created using
XMLEncoder . |
Encoder |
Uses persistence delegates to break an object graph down into a
series of Statement s and Expression s that
can be used to recreate it. |
XMLEncoder |
An Encoder that produces statements and
expressions in an XML encoding. |
PersistenceDelegate |
An abstract class that defines objects that can express the state of another object using the public methods of that object's class. |
DefaultPersistenceDelegate |
The persistence delegate used, by default, for beans. |
See JavaBeans Component API for links
to where you can find more information about long-term
persistence.
The following classes were also added in v1.4:
Class | Description |
---|---|
EventHandler |
Provides support for dynamically generating event listeners that have a small footprint and can be saved automatically by the persistence scheme. |
ExceptionListener |
Defines a listener to be notified when a exception was thrown
but then recovered from. You can register an exception listener on
an XMLEncoder or XMLDecoder object to be
notified when the object encounters a recoverable problem while
writing or reading a bean. |
PropertyChangeListenerProxy |
A proxy that implements PropertyChangeListener and
serves to group another PropertyChangeListener (the
real event handler) with a specific property; the proxy forwards
property change events to the real event handler. |
VetoableChangeListenerProxy |
A proxy that implements VetoableChangeListener and
serves to group another VetoableChangeListener (the
real event handler) with a specific constrained property; the proxy
forwards vetoable property change events to the real event
handler. |
The following classes have additional methods:
PropertyChangeSupport
class now contains a no-argument method to get all the registered
property change listeners:
getPropertyChangeListeners
.VetoableChangeSupport
class now contains a no-argument method to get all the registered
vetoable change listeners:
getVetoableChangeListeners
.Introspector
class has been reimplemented, and its performance has improved. The
new implementation has caused the following changes in the behavior
of the introspector:
FeatureDescriptor
s are now shared on a
per-BeanInfo
basis, rather than copied when the
BeanInfo
is returned. This change improves the
performance of the getBeanInfo
method. It also means
that when an attribute/value in a FeatureDescriptor
changes, that change is persistent among getBeanInfo
invocations as long as the BeanInfo
is not garbage
collected. (Garbage collection of BeanInfo
s is
described in Garbage Collection and Custom
Attributes.)getBeanInfo
methods no longer create a copy of
the requested BeanInfo
. Instead, they cache the
BeanInfo
and return it. If necessary, you can get the
old behavior by storing a reference to the returned
BeanInfo
and using the flushFromCaches
method to flush the bean's class from the introspector's
cache.instantiate
method can't instantiate a
particular class using the sibling or bootstrap class loader, it
now tries to load the class using the current thread's class
loader.As of v 1.4, a BeanInfo
can be garbage collected
when no direct references to it exist and the system is low on
memory. This is implemented in the Introspector
by
wrapping BeanInfo
s in SoftReference
s.
The possibility of garbage collection affects how you store
custom attributes inside BeanInfo
s. If a particular
BeanInfo
is garbage collected, then the next time you
invoke Introspector.getBeanInfo
to get the
BeanInfo
, the returned object won't contain any custom
attributes.
To avoid this problem, if you store custom attributes inside a
BeanInfo
you must ensure that the
BeanInfo
is correctly initialized with those
attributes every time you retrieve the BeanInfo
. The
following is an example of initializing a BeanInfo
class with a custom property in the bean descriptor. The code would
be similar for a custom attribute in a property descriptor, method
descriptor, or event set descriptor.
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); }