Property Access Event Firing

Chapter 7 • Software Components 255

7.3 Computational Reflection

Computational reflection is a technique that allows a system to maintain information about itself meta-information and use this information to change its behavior adapt. As shown in Figure 7-2, computational reflection refers to the capability to introspect and represent meta-level information about data or programs, to analyze and potentially modify the meta-level representation of the data, and finally to reify such changes in the metadata so that the original data or programs behave differently. It should be noted that the notion of data is universal in that it includes data structures in a program used in the source code. This is achieved by processing in two well-defined levels: functional level also known as base level or application level and management or meta level. Aspects of the base level are represented as objects in the meta-level, in a process known as reification see below. Meta-level architectures are discussed in Section 2.2 and reflective languages in Section 2.3. Finally, Section 2.4 shows the use of computational reflection in the structuring and implementation of system- oriented mechanisms. http:cliki.tunes.orgReflection

7.3.1 Run-Time Type Identification

If two processes communicate externally to send and receive data, what happens when the data being sent is not just a primitive or an object whose type is known by the receiving process? In other words, what happens if we receive an object but do not know anything about it—what instance variables and methods it has, etc. Another way to pose the question: What can we find out about the type of an object at run-time? Metadata Data Introspection Reification Figure 7-2: Computational reflection consists of two phases: i an introspection phase, where data is analyzed to produce suitable metadata, and ii a reification phase, where changes in the metadata alter the original behavior of the data it represents. Ivan Marsic • Rutgers University 256 A simple way to solve this problem is to check for all possible objects using instanceof, the operator that lets you test at run-time, whether or not an object is of a given type. A more advanced way is supported by the java.lang.reflect package, which lets you find out almost anything you want to know about an object’s class at run-time. An important class for reflection is the class Class, which at first may sound confusing. Each instance of the class Class encapsulates the information about a particular class or interface. There is one such object for each class or interface loaded into the JVM. There are two ways to get an instance of class Class from within a running program: 1. Ask for it by name using the static method forName: Class fooClass = Class.forNameFoo; This method will return the Class object that describes the class Foo 2. Ask an instance of any Object for its class: Foo f = new Foo; Class fooClass = f.getClass; As a side note, this construct is legal: Class classClass = Class.forNameClass; It returns back the instance of Class that describes the class Class. Once you have a Class object, you can call methods on it to find out information about the class. None of the methods are mutators, so you cannot change the class at run-time. However, you can use it to create new instance of a class, and to call methods on any instance. Some of the methods available in class Class are: Constructor getConstructorClass[] paramTypes; Constructor[] getConstructors; Field getFieldString name; Field[] getFields; Method getMethodString name, Class[] paramTypes; Method[] getMethods; boolean isInstanceObject obj; boolean isPrimitive; String getName;