Introduction
Bean Concepts
Properties and Design Patterns
Implicit Introspection
Explicit Introspection
Reflection
Serialization
Next Topic: Network Communication
The goal is to be able to write tools that do not have to be recompiled in order to be used. A "beans aware" builder tool maintains Beans in a pallette or toolbox. You can:
The builder tool should not need any predefined knowledge of the Bean. This allows new Beans to be added at any time.
For example, a Java Label has a text field that can be set with setText and gotten with getText. Part of the reason for the many name changes between JDK 1.0 and JDK 1.1 is an attempt the follow this new naming convention. For example, the component method bounds was changed to getBounds. There is also a setBounds method.
As another example, the resize method of a component has been renamed to setSize and there is also a getSize method.
For boolean variables, instead of using a get method, an is method is used. For example, a TextComponent has a property called editable which indicates whether the text can be edited. It is set with setEditable(boolean) and tested with isEditable.
If the methods of a property are public, the property is said to be exposed.
It can find out about properties of a bean by either an implicit or explicit method. The implicit method uses design patterns.
The Introspector creates a list of all of the public methods in the bean and searches that list for signatures that match a particular pattern.
Suppose that the following signature is found:
Here are some of the design patterns currently supported:
get/set
These indicate that the Bean has a property propertyName of class PropertyType.
If either of these is detected, the introspector creates a property descriptor for the property called propertyName which is the decapitalized version of PropertyName.
is/get/set
As above for boolean variable if any of these are detected.
Indexed Property Pattern
Public Method Pattern
The introspector creates method descriptors for all of the bean's public
methods including all of the public methods of the bean's superclasses.
Multicast Event Set Pattern
If both signatures are detected, the introspector creates an event set descriptor for an event set called eventName which is the decapitalized version of EventName.
For example, the presence of the following methods indicates that the bean fires action event sets that will be processed by ActionListeners:
public void addActionListener(ActionListener listener) public void removeActionListener(ActionListener listener)
The Introspector first appends BeanInfo to the package-qualified class name of the bean and then tries to instantiate a class with that name. If this does not work it tries the search path.
If successful it eventually finds a BeanInfo for the Bean. The getBeanInfo method takes a Bean class object as a parameter and returns a BeanInfo object.
The BeanInfo class contains a number of get methods for obtaining information about a bean, such as getEventSetDescriptors which contains information about the kinds of events fired by this bean.
The getPropertyDescriptors method returns an array of PropertyDescriptor objects, each of which can be used to get information on a property of the Bean.
There are two types of applications that are likely to use reflection.
More explicitly, suppose you had a variable of type MyClass and a String,
MyMethod, which is the name of a method in the class MyClass.
How would you execute that method?
Reflection allows you to create a reflected class from a given instance of a class. The reflected class allows you to:
Among the methods in the class Method are:
For example, the following method is part of the Array class:
public static Object newInstance(Class componentType, int length)
creates a new array, like the creation expression:
It supports the complementary reconstruction of the object from the stream.
This is useful for
FileOutputStream f = new FileOutputStream("tmp"); ObjectOutputStream s = new ObjectOutputStream(f); s.writeObject("Today"); s.writeObject(new Date()); s.flush();Both String and Date implement Serializable.
To read these back you could use:
FileInputStream in = new FileInputStream("tmp"); ObjectInputStream s = new ObjectInputStream(in); String today = (String)s.readObject(); Date date = (Date)s.readObject();Object serialization is automatic for classes that implement the Serializable interface. To make an object Serializable, you need only implement Serializable, and do not need to implement any additional methods as long as all of the components are primitive or implement Serializable. Values of all fields are saved unless they are declared transient.
If you want to have control over how the object is converted to a stream of bytes, you can implement the Externalizable interface. This requires that you write the following two methods:
public void writeExternal(ObjectOutput out) throws IOException public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExceptionOne of the problems with doing this yourself is versioning. The Serializable interface takes care of problems with storing under a different version of Java than the reading.