Reflection
The Reflection API consists of two components:
Objects that represent the various parts of a class file
It is the mechanism used to fetch information about a class. This mechanism is built into the class named Class. The special class Class is the universal type for the meta information that describes objects within the Java system. Class loaders in the Java system return objects of type Class.
The three most interesting methods in this class were:
1. For Name, which would load a class of a given name, using the current class loader.
2. Get Name, which would return the name of the class as a String object,which was useful for identifying object references by their class name.
3.New Instance, which would invoke the null constructor on the class and return you an object instance of that class of object.
The Reflection API adds some additional methods to class to these three useful methods.
These are:
1. Get Field
2. Get Fields
3. Get Declared Fields
4. GetConstructor
5. GetConstructors
6. GetDeclaredConstructor
7. GetDeclaredClasses
8. GetSuperclass
9. GetInterfaces
10. Get Method
11. Get Methods
12. Get Declared Methods
A means for extracting those objects in a safe and secure way.
This is very important, as Java provides many security safeguards, and it would not make sense to provide a set of classes that invalidated those safeguards.
Many new classes were added to represent the objects that these methods would return in addition to these methods . The new classes mostly are part of the java.lang.reflect package, but some of the new basic type classes (Void, Byte, and so on) are in the java.lang package. The decision was made to put the new classes where they are by putting classes that represented meta-data in the reflection package and classes that represented types in the language package.
So, the Reflection API represents a number of changes to class Class that let you ask questions about the internals of the class, and a bunch of classes that represent the answers that these new methods give you.
Usage of the Reflection API
The Reflection API is symmetric means if you are holding a Class object, you can ask about its internals, and if you have one of the internals, you can ask it which class declared it. Thus you can move back and forth from class to method to parameter to class to method, and so on. One interesting use of this technology is to find out most of the interdependencies between a given class and the rest of the system.
Collection of class references
1.With the package statement taken care of, we proceed to Step 1, which is to collect all of the other class names that are referenced by this class. This collection process is shown in the code below:
ff = c.getDeclaredFields();
for (int i = 0; i < ff.length; i++) {
x = tName(ff[i].getType().getName(), classRef);
}
In the above code, the array ff is initialized to be an array of Field objects. The loop collects the type name from each field and process it through the tName method. The tName method is a simple helper that returns the shorthand name for a type. So java.lang.String becomes String. And it notes in a hashtable which objects have been seen. At this stage, the code is more interested in collecting class references than in printing.
2.The next source of class references are the parameters supplied to constructors. The next piece of code, shown below:
cn = c.getDeclaredConstructors();
for (int i = 0; i < cn.length; i++) {
Class cx[] = cn[i].getParameterTypes();
if (cx.length > 0) {
for (int j = 0; j < cx.length; j++) {
x = tName(cx[j].getName(), classRef);
}
}
}
As you can see, I've used the getParameterTypes method in the Constructor class to feed me all of the parameters that a particular constructor takes. These are then processed through the tName method.
Conclusion
An interesting thing to note here is the difference between the method get Declared Constructors and the method getConstructors. Both methods return an array of constructors, but the getConstructors method only returns those constructors that are accessible to your class. This is useful if you want to know if you actually can invoke the constructor you've found, but it isn't useful for this application because I want to print out all of the constructors in the class, public or not. The field and method reflectors also have similar versions, one for all members and one only for open associates.