Documentation Contents

# API Enhancements to the JavaBeans Component API in v1.4

This document describes changes to the `java.beans` package that were introduced in Java SE 1.4:

- New API for Long-Term Persistence
- Other API Additions
- Changes to the Introspector
- Garbage Collection and Custom Attributes

## New API for Long-Term Persistence

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.

## Other API Additions

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:

- The `PropertyChangeSupport` class now contains a no-argument method to get all the registered property change listeners: `getPropertyChangeListeners`.
- Similarly, the `VetoableChangeSupport` class now contains a no-argument method to get all the registered vetoable change listeners: `getVetoableChangeListeners`.

## Changes to the Introspector

The `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.)
- The `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.
- If the `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.

## Garbage Collection and Custom Attributes

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);
    }

Copyright © 1993, 2026, Oracle and/or its affiliates. All rights reserved.
Contact Us