> The following documentation will help you learn about reflection, introspection, and the `BeanInfo` class:
> - Chapter 8 of the

> - Core Reflection Documentation:
>   - trail
>   - documentation

> - Beans API Documentation:
>   - interface
>   - class
>   - class
>   - class
>   - class
>   - class
>   - class
>   - class
>   - class
>   - class
> How does a builder tool examine a Bean and expose its features (properties, events, and methods) in a property sheet? By using the `java.beans.Introspector` class. The `Introspector` class uses the JDK core reflection API to discover a Bean's methods, and then applies the JavaBeans design patterns to discover the Beans features. This discovery process is named introspection.

> Alternatively, you can explicitly expose a Bean's features in a separate, associated class that implements the `BeanInfo` interface. By associating a `BeanInfo` class with your Bean, you can:

> - Expose only those features you want to expose.
> - Rely on `BeanInfo` to expose some Bean features while relying on low-level reflection to expose others.
> - Associate an icon with the target Bean.
> - Specify a customizer class.
> - Segregate features into normal and expert categories.
> - Provide a more descriptive display name, or additional information about a Bean feature.

> `BeanInfo` defines methods that return descriptors for each property, method, or event that you want exposed. Here's the prototypes for these methods: PropertyDescriptor[] getPropertyDescriptors(); MethodDescriptor[] getMethodDescriptors(); EventSetDescriptor[] getEventSetDescriptors(); Each of these methods returns an array of descriptors for each feature.

### Feature Descriptors

> `BeanInfo` classes contain descriptors that precisely describe the target Bean's features. The BDK implements the following descriptor classes:

> - `FeatureDescriptor` is the base class for the other descriptor classes. It declares the aspects common to all descriptor types.
> - `BeanDescriptor` describes the target Bean's class type and name, and describes the target Bean's customizer class if it exists.
> - `PropertyDescriptor` describes the target Bean's properties.
> - `IndexedPropertyDescriptor` is a subclass of `PropertyDescriptor`, and describes the target Bean's indexed properties.
> - `EventSetDescriptor` describes the events the target Bean fires.
> - `MethodDescriptor` describes the target Bean's methods.
> - `ParameterDescriptor` describes method parameters.

> The `BeanInfo` interface declares methods that return arrays of the above descriptors.

### Creating a BeanInfo Class

> This section uses the `ExplicitButtonBeanInfo` demo class to illustrate creating a `BeanInfo` class. Here are the general steps to make a `BeanInfo` class:

> 1. Name your `BeanInfo` class. You must append the string "BeanInfo" to the target class name. If the target class name is `ExplicitButton`, then its associated Bean information class must be named `ExplicitButtonBeanInfo`

> 2. Subclass `SimpleBeanInfo`. This is a convenience class that implements `BeanInfo` methods to return null, or an equivalent no-op value. public class ExplicitButtonBeanInfo extends SimpleBeanInfo { Using `SimpleBeanInfo` saves you from implementing all the `BeanInfo` methods; you only have to override those methods you need.

> 3. Override the appropriate methods to return the properties, methods, or events that you want exposed. `ExplicitButtonBeanInfo` overrides the `getPropertyDescriptors()` method to return four properties: public PropertyDescriptor[] getPropertyDescriptors() { try { PropertyDescriptor background = new PropertyDescriptor("background", beanClass); PropertyDescriptor foreground = new PropertyDescriptor("foreground", beanClass); PropertyDescriptor font = new PropertyDescriptor("font", beanClass); PropertyDescriptor label = new PropertyDescriptor("label", beanClass); background.setBound(true); foreground.setBound(true); font.setBound(true); label.setBound(true); PropertyDescriptor rv[] = {background, foreground, font, label}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } } There are two important things to note here:
>    - If you leave a descriptor out, that property, event or method will not be exposed. In other words, you can selectively expose properties, events, or methods by leaving out those you don't want exposed.
>    - If a feature's getter (for example, `getMethodDescriptor()`) method returns null, low-level reflection is then used for that feature. This means, for example, that you can explicitly specify properties, and let low-level reflection discover the methods. If you don't override the `SimpleBeanInfo` default method, which returns null, low-level reflection will be used for that feature.

> 4. Optionally associate an icon with the target Bean. public java.awt.Image getIcon(int iconKind) { if (iconKind == BeanInfo.ICON_MONO_16x16 || iconKind == BeanInfo.ICON_COLOR_16x16 ) { java.awt.Image img = loadImage("ExplicitButtonIcon16.gif"); return img; } if (iconKind == BeanInfo.ICON_MONO_32x32 || iconKind == BeanInfo.ICON_COLOR_32x32 ) { java.awt.Image img = loadImage("ExplicitButtonIcon32.gif"); return img; } return null; } The BeanBox displays this icon next to the Bean name in the ToolBox. You can expect builder tools to do the same.

> 5. Specify the target Bean `class`, and, if the Bean has a customizer, specify it also. public BeanDescriptor getBeanDescriptor() { return new BeanDescriptor(beanClass, customizerClass); } ... private final static Class beanClass = ExplicitButton.class; private final static Class customizerClass = OurButtonCustomizer.class;

> Keep the `BeanInfo` class in the same directory as its target class. The BeanBox first searches for a target Bean's `BeanInfo` class in the target Bean's package path. If no `BeanInfo` is found, then the Bean information package search path (maintained by the `Introspector`) is searched. The default Bean information search path is `sun.beans.infos`. If no `BeanInfo` class is found, then low-level reflection is used to discover a Bean's features.

### Using BeanInfo to Control What Features are Exposed

> If you rely on low-level reflection to discover your Bean's features, all those properties, methods, and events that conform to the appropriate design patterns will be exposed in a builder tool. This includes any features in all base classes. If the BeanBox finds an associated `BeanInfo` class, then that information is used instead, and no more base classes are examined using reflection. In other words, `BeanInfo` information overrides low-level reflection information, and prevents base class examination.

> By using a `BeanInfo` class, you can expose subsets of a particular Bean feature. For example, by not returning a method descriptor for a particular method, that method will not be exposed in a builder tool.

> When you use a `BeanInfo` class:

> - Base class features will not be exposed. You can retrieve base class features by using the `BeanInfo.getAdditionalBeanInfo` method.

> - Properties, events, or methods that have no descriptor will not be exposed. For a particular feature, only those items returned in the descriptor array will be exposed. For example, if you return descriptors for all your Bean methods except `foo`, then `foo` will not be exposed.

> - Low-level reflection will be used for features with getter methods returning null. For example if your `BeanInfo` class contains this method implementation: public MethodDescriptor[] getMethodDescriptors() { return null; } Then low-level reflection will be used to discover your Bean's public methods.

### Locating BeanInfo Classes

> Before examining a Bean, the `Introspector` will attempt to find a `BeanInfo` class associated with the Bean. By default, the `Introspector` takes the target Bean's fully qualified package name, and appends "BeanInfo" to form a new class name. For example, if the target Bean is `sunw.demo.buttons.ExplicitButton`, then the `Introspector` will attempt to locate `sunw.demo.buttons.ExplicitButtonBeanInfo`.

> If that fails, then each package in the `BeanInfo` search path is searched. The `BeanInfo` search path is maintained by `Introspector.setBeanInfoSearchPath()` and `Introspector.getBeanInfoSearchPath()`.