Mirror, mirror, on the wall...
No, this is not about me looking at myself, or even my own code. Rather, it's my nomination for the Beautiful Code API. There is plenty of beautiful stuff in the Java SE API, but to my mind one of the most sublime pieces is Sun's Reflection API. While some dynamic languages let you do what Reflection does, I'm not aware of any other compiled, strongly-typed language (other than, perhaps, Java knock-offs like C#) that have anything like it.
So what is Reflection? Also known as Introspection, the Reflection API allows you to operate on classes and objects in ways such as the following:
- Load a class file into memory at run time, knowing only its name;
- Given a class, examine its methods, fields, constructors, annotations, and so on;
- Given a class, invoke constructors and methods;
- Given a class and an instance, access fields;
- Given an interface, create proxies for it dynamically.
A class named Class
It might seem strange to have "a class named Class" (maybe no more so than creating an object of class Object, I guess). But java.lang.Class has been around since the earliest days of Java; at least JDK 1.0, so I guess most of these uses were planned even then.
Time for a code example. Suppose you've invented a new API called a Showlet, sort of a cross between an Applet and a Servlet. You think lots of people will want to write their own Showlets. Create an interface for it:
package showoff;
public interface Showlet {
public void show();
}
Publicize it (this step omitted from this article; you're on your own). Now whenever somebody wants to write a showlet, they just implement your public interface. Say I write one called IanShow:
package com.darwinssys.jellybeans;
import showoff.Showlet;
public class IanShow implements Showlet {
public void show() {
System.out.println("OK, here's what I show: A234JQ");
}
}
Nothing very elaborate, but enough to show (so to speak) the operation. Your code will need to load this class, even though my class was written after your class, so you can't have a compile-time dependency on my class. However, to use it is no problem:
public class MyBigApp {
public static void main(String[] args) throws Exception {
String className;
// stub getting name of user-defined class from config file
className = "com.darwinsys.jellybeans.IanShow";
// Create this user's ShowLet
Class c = Class.forName(className);
Showlet s = (Showlet)c.newInstance();
// Now we have a showlet, make it do its thing:
s.show();
}
}
The whole magic part is the two lines of code below the comment "Create this user's Showlet". The first line uses the Class class' static forName() method to dynamically load the IanShow.class file from your classpath into the JVM. At this time the class file will be found, inspected, verified, and loaded into memory; after this it is treated pretty much like any other class in your application. The second line creates an instance of this class. The main requirement for this to succeed is that there must be a public, no-argument constructor in your class. Since this is the default constructor in Java, it's a safe bet. But in case the user messes up, one of a variety of Exceptions is just waiting to be thrown. See the JavaDoc, or compile this code in an IDE with the throws clause commented out. In a real "extensible application" model, you'd want to catch some of these and give better warnings.
One of the most annoying problems is ClassCastException, which would happen if the user provided a class that doesn't implement the Showlet interface. This would occur after the newInstance() call but before the assignment to variable "s". To prevent this exception, you'd normally use the built-in instanceof operator, but that requires the class be known at compile time. There is an isInstance method in the Class class; a more cautious version of the Showlet creation is thus:
Class c = Class.forName(className);
Object o = c.newInstance();
if (o instanceof Showlet) {
Showlet s = (Showlet)c.newInstance();
...
} else {
System.err.printf("Sorry, class %s is not a Showlet%n",
className);
}
What does all this give you? An extension or plug-in mechanism that is completely independent of user-defined classes. As long as they correctly implement your published interface, they will load and run.
Plan B
If for some reason you prefer inheritance, make Showlet be an abstract class with show() an abstract method. The instance classes then extend this rather than implement it. Everything else is pretty much the same.
Getting to Class
Class.forName() is one way of getting a Class descriptor, and it's familiar to anybody who's written a "JDBC 101" program (even though it's not how you get your database driver in real life). There are two other ways of getting a Class descriptor.
If the class whose descriptor you want is known at compile time, just say typeName.class. The "class" keyword in Java, if it appears after a "." with a type name before that, generates an expression of type "Class" for the given type. So String.class returns the same as Class.forName("java.lang.String"), for example.
Finally, if the class is not known but you have an object of the class, you can ask it for its class.
Class c = someRandomObject.getClass();
println("Object is of class " + c.getName());
What does this give you? One way or another, you should now be able to get a Class descriptor for any class in a Java program.
MyJavaP
The standard JDK has always included a program called javap, the Java printer. Javap has two main functions: it provides a quick view of a class' external structure, and it provides a detailed dump of a class' internal byte code. The latter is beyond the scope of the Reflection API; you would have to use a byte code library such as the Apache Byte Code Engineering Library (BCEL). The former, however, can easily be implemented using Reflection. When run against java.lang.Object, the Java SE implementation produces this output:
Compiled from "Object.java"
public class java.lang.Object{
public java.lang.Object();
public final native java.lang.Class getClass();
public native int hashCode();
public boolean equals(java.lang.Object);
protected native java.lang.Object clone() throws java.lang.CloneNotSupportedException;
public java.lang.String toString();
public final native void notify();
public final native void notifyAll();
public final native void wait(long) throws java.lang.InterruptedException;
public final void wait(long, int) throws java.lang.InterruptedException;
public final void wait() throws java.lang.InterruptedException;
protected void finalize() throws java.lang.Throwable;
static {};
}
I wrote a simple clone of javap, called MyJavaP.
An earlier version of this was contributed to the
Kaffe project.
The output is as follows:
class java.lang.Object {
public java.lang.Object()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
protected void java.lang.Object.finalize() throws java.lang.Throwable
protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
}
As you can see, it misses some details, and the static code block.
But, for a simple implementation (about sixty lines), it does not badly.
The core of the implementation is shown in these twenty lines of code:
Class c = Class.forName(className);
System.out.println(c + " {");
int mods;
Field fields[] = c.getDeclaredFields();
for (Field f : fields) {
if (!Modifier.isPrivate(f.getModifiers())
&& !Modifier.isProtected(f.getModifiers()))
System.out.println("\t" + f);
}
Constructor[] constructors = c.getConstructors();
for (Constructor con : constructors) {
System.out.println("\t" + con);
}
Method methods[] = c.getDeclaredMethods();
for (Method m : methods) {
if (!Modifier.isPrivate(m.getModifiers())) {
System.out.println("\t" + m);
}
}
System.out.println("}");
Membership Lists
Suppose you want to become a famous Java author by creating a big fat book full of API cross-reference. Knowing there are new releases of Java SE every 12-18 months, do you:
- a) Read the javadoc, and type up a huge document with all the information for each class, or
- b) Write a program that extracts all this information mechanically, and sends it direct to your typesetting program?
The basic idea for the cross reference program, then, expressed as pseudo-code, is:
for (ZipEntry entry : new ZipFile(name).entries()) {
if (entry represents a Class) {
Class c = Class.forName(entry.getName());
for (Field f : c.getMethods()) {
print a field;
}
for (Method m : c.getMethods() {
print a method;
}
}
}
Of course, the real code is a bit more complex. And, in fact, I wrote it with the view that I might want to re-use parts of the code, so the outer loop and the "if entry represents a class" logic are in the abstract class APIFormatter; the logic of what to do with a given class is deferred to the template method doClass() in a subclass. The standard example is CrossRef, but there is another usage example in the JUnit test case APIFormatterTest. Finally, CrossRefXML extends CrossRef and overrides some of the output methods to output an XML document instead of a text document.
JavaBean Introspector
Several APIs use classes from the Reflection API. The JavaBeans API (java.beans) was both designed as a simplification layer to make it easier to use reflection for the less-ambitious task of getting an object's list of "properties" - fields that have setter/getter method pairs- and hence to make it easy for GUI builder tools to discover information about "Java Beans". The spec included the now-well-known setter/getter accessor pattern, requirement of a no-argument constructor, and the optional BeanInfo configuration file. Sun hoped and expected that tool building companies would produce GUI builders (based on JavaBeans) that would compete with Visual Basic. Arguably they have done so, in tools like Eclipse and NetBeans with their respective visual builders.The Introspector is the main class you need to know. Its getBeanInfo() method takes a class name and returns a general-purpose BeanInfo object. This represents the list of properties either exposed by the bean or specified in the eponymous configuration file.
A new methodology - Dynamic Method Invocation
If you have a Method descriptor, you can invoke that method on any object of a class that contains it. Just call the Method's invoke() method passing the object (you can pass null if you're invoking a static method), and the argument list packed as an array of Object. Assume you are given class X containing this method:
public void work(int i, String s) {
System.out.printf("Called: i=%d, s=%s%n", i, s);
}
To find and invoke this method dynamically, given an instance of it
called "x", all you need to do is:
Class clX = x.getClass();
// To find a method, need array of matching Class types.
Class[] argTypes = { int.class, String.class };
// Find a Method object for the given method.
Method worker = clX.getMethod("work", argTypes);
// To invoke the method, need the invocation
// arguments, as an Object array.
Object[] theData = { 42, "Chocolate Chips" };
// The last step: invoke the method.
worker.invoke(x, theData);
By itself this is a bit tedious to code, but it is background for the next few sections.
Dynamic Proxy and AOP
The Proxy pattern is well known: one object stands in for another. A Proxy can be created in Java using an interface and two classes, the "real" implementation and a surrogate or wrapper which implements the same interface and ultimately forwards each method call through to the "real" implementation. For example, if I want to create a Proxy for the Showlet example above, say, to verify the user's credentials before passing control to the provided Showlet, a do-nothing proxy impementation can be as simple as this:
public class ShowletProxy implements Showlet {
Showlet realObject; // set in constructor
public void show() {
realObject.show();
}
}
In real life the Proxy can do all sorts of other things, such as testing security, logging method calls and their parameters, network calls (used in RMI and EJB), and so on.
A more complete hand-written Proxy might look like this:
public class ShowletProxy implements Showlet {
Showlet realObject; // set in constructor
public void show() {
final String className = realObject.getClass().getName();
if (securityOK()) {
log("About to call " + className);
realObject.show();
log("Completed " + className);
} else {
log("Security - rejected " + className);
}
}
}
The downside of this is that it is tied to a particular interface, namely Showlet. What if you want to proxy ten, a hundred, or a thousand classes? It just doesn't scale. You need a way to write the proxies dynamically. That is, of course, the dynamic proxy mechanism. Introduced to Java in Java SE 1.3, the dynamic proxy mechanism in class java.lang.reflect.Proxy allows you to create a proxy to any interface dynamically, given only the interface and a general-purpose InvocationHandler. The InvocationHandler is where you specify what to do before and after the method invocation. An InvocationHandler allows you full control over the actual invocation of methods in the "real" object that is being proxied. There is only one method in the Invocation handler interface; a typical implementation might look something like this:
class MyInvocationHandler implements InvocationHandler {
private Object realObject; // set in Constructor
/**
* Method that is called for every call into the proxy;
* this has to invoke the method on the real object.
*/
public Object invoke(Object proxyObject, Method method, Object[] argList)
throws Throwable {
log("About to call " + className + "." + method.getName());
Object ret = method.invoke(realObject, argList);
System.out.println(" Completed.");
return ret;
}
}
The InvocationHandler's invoke() method is where the dynamic proxy calls your code; the "method.invoke()" is where your proxy calls the real object's method. The names are the same, but they are different steps along the chain, and the argument lists differ. Although the InvocationHandler's invoke() method is passed a reference to the dynamic proxy, it is not passed an reference to the "real" object, so this has to be provided in the class, either by a Constructor or (for greater flexibility) in a set method.
To create the dynamic proxy, use the Proxy class' newProxyInstance() method, which requires a ClassLoader (see below), one or more interfaces that are to be handled (as an array of Class objects), and a reference to the InvocationHandler:
Showlet generatedProxy = (Showlet) Proxy.newProxyInstance(
Showlet.class.getClassLoader(),
new Class[] { Showlet.class }, handler);
Because it's a nuisance to create the InvocationHandler and the Dynamic Proxy, this is normally delegated to a Factory method. Factory is another well-known design pattern used throughout Java: a class makes up objects for you (see for example Locale.getInstance() and Calendar.getInstance()).
In the code download you will find a class called DynamicProxyFactoryDemo which implements a Factory for the proxies; note that the main program now has no idea that proxying is going on; it deals only in the interface (and the factory).
public static void main(String[] args) {
Showlet showlet = ShowletFactory.getInstance();
System.out.println("Showlet Proxy object is " +
showlet.getClass().getName());
System.out.println("All done");
}
What does this give you? With Dynamic Proxy, you can create one
proxy that will proxy all (or selected) requests for a huge number of
methods on a large number of objects.
However, the proxying has some setup complexity, so it's best
if you can abstract object creation into the factory.
Aspects of change
A more generic way of handling this notion of proxying is to use programming language constructs to help automate it. This has lead to the rise of "Aspect Oriented Programming", or AOP. AOP uses some interesting vocabulary, but an "Aspect" is some function (such as logging or validation) that needs to applied automatically to a range of classes. Two important AOP implementations are Aspect/J (original site at PARC; current site at Eclipse.org) and the Spring Framework AOP. Spring provides a very general-purpose Bean Factory that is configured entirely by a configuration file, and a large array of pre-written beans. Useful in this context is their AutoProxyFactoryBean, which will automatically apply proxying to an arbitrary number of methods based on several seclection mechanisms, including one that uses Regular Expressions.
Since I'm sure there will be a BC article on Spring, I won't steal this article's thunder, but if you want a peek meantime, check out the Spring Framework site.
ClassLoaders and SecurityManagers and more, oh my
One topic I've not covered here is the notion of security. Java provides a SecurityManager class that can be used to limit what classes can do. A ClassLoader is, of course, the object that is responsible for loading classes. Java provides a default ClassLoader, but you can write your own. The topics of ClassLoaders and SecurityManagers are important, but this article is already at its maximum length. I urge you to learn about these topics, especially if you are going to be using dynamic classloading of classes provided by other, possibly untrusted, entities. These topics are discussed in my Java Cookbook (O'Reilly, 2e 2004) as well as in the Sun-provided documentation.
Conclusion
The Reflection API is truly sublime, because it allows your code to reach down into the JVM and do some of the same things that the Java runtime does: discover and load class files, instantiate classes, discover and invoke constructors and methods, discover and set/get fields, and more. In this Beautiful Code, I've shown some real-world code that uses this beautiful API.
Footnote: Downloads
The examples in this article are mostly drawn from the code that accompanies my Java Cookbook (my page; O'Reilly page), although the code has been updated since the Second Edition went to print. You can download the entire zip file if you wish. There is also a much smaller zip file of just the examples from the Reflection package (subdirectory) of the Java Cookbook. Note that some of the later examples use an interface called Quote instead of Showlet, but the functionality of the proxying is the same. The Quote service gives out pithy sayings, not stock price quotations.
Ian Darwin is the author of O'Reilly's Java Cookbook, but also wrote the Nutshell book Checking C Programs with Lint and more recently Checking Java Programs with Open Source Tools; he is also co-author of the 1985 cult classic "Can't Happen, or /* NOTREACHED */, or Real Programs Dump Core" which in its way and in its day taught developers to change ugly code into beautiful code.

Comments (12)
"While some dynamic languages let you do what Reflection does, I'm not aware of any other compiled, strongly-typed language (other than, perhaps, Java knock-offs like C#) that have anything like it."
Distinguishing between compiled and interpreted languages is pointless - consider Perl and Lisp, where it makes no difference to behaviour whether something is compiled or interpreted. This is known as Ousterhout's Dichotomy.
"strongly-typed" is an overloaded term usually meaning more capable in some way than something the author considers to be poor for some reason. See What To Know Before Debating Type Systems.
Now try writing your code without "throws Exception", a known Java anti-pattern. Then tell me it's beautiful.
Posted by Ricky Clarkson | August 8, 2007 10:00 PM
Class c = Class.forName(className);
Object o = c.newInstance();
if (c.isInstance(o)) {
it is always true for the if statement.
Posted by khtam | August 8, 2007 11:57 PM
This isn't particular to this topic, but - could you add a printable page option to your site? I'd like to be able to (beautifully!) print the longer articles.
Posted by Eric | August 9, 2007 8:16 AM
This example:
Class c = Class.forName(className); Object o = c.newInstance(); if (o instanceof Showlet) { Showlet s = (Showlet)c.newInstance(); ... } else { System.err.printf("Sorry, class %s is not a Showlet%n", className); }looks wrong to me. In the context discussed, should it not be:
Class c = Class.forName(className); if (c.isInstance(Showlet.class)) { Showlet s = (Showlet)c.newInstance(); ... } else { System.err.printf("Sorry, class %s is not a Showlet%n", className); }??
Posted by Jules | August 9, 2007 9:03 AM
While it's true that the reflection API allows very flexible constructs, it also makes them very weak, and error-prone. It also breaks loads of refactoring features. It enables you to loose all the advantages of Java being strong-typed.
I think telling the average Java dev to use reflection is like telling him to use C++. He will never be as carefull as a real C++ dev about memory management, and the code will be ugly, and difficult to maintain. Trying not to use the reflection API can help you use the compiler to correct errors, while the reflection API needs a lot more of runtime testing.
Posted by Kevin POCHAT | August 9, 2007 9:32 AM
Ok, I have to comment here. This weblog is about beauty in code, and in this case about a Java API. But what in the hell means 'forName'?
Ever since the first time I encountered this method I have never understood what 'forName' means. Is it 'for' just like "This is for you" or is 'for' an abbreviation. Anyway, I don't think it's an English word, is it?
Posted by Mike | August 9, 2007 10:00 AM
The reflection API is certainly powerful, but I've always found it esthetically deficient. Your code samples do illustrate the capabilities of the API, but they leave out the dozens of lines of exception handling that reflection always necessitates.
For comparison, consider how Objective-C extracts a "method reference" with the @selector() operator. Or, Ruby's dynamic method invocation with someObject.send("someMethod").
Those supply the same power (or greater, in the case of "doesNotUnderstand") and they result in much more elegant code.
Posted by Nygard | August 9, 2007 11:11 AM
The Author Responds...
Ricky, thanks for your comments. The article about type systems is a good one, and anyone interested should read it.
Two of you (Ricky and Nygard) commented on error handling, and I agree that "checked exceptions" is not necessarily a beautiful idea...
Two of you (khtam and Jules) commented on the "thinko" in the "instance of" example, which has been corrected; thanks.
Kevin, you are correct that Reflection is not for beginners, which is why it's usually not taught at the "Java 101" level. It is nonetheless a powerful tool and a good thing to know about.
Thanks everybody for the comments! --Ian
Posted by Ian Darwin | August 9, 2007 11:56 AM
Mike: the "forName" is a method name formed of two words, "for name", like getType() is read as 'get Type'. "Class.forName()" means "load the class for the given class name". Very early on in Java they weren't as careful about naming methods consistently; today they might well call it something different.
--Ian
Posted by Ian Darwin | August 9, 2007 11:59 AM
Thanks for clearing that up Ian!
Posted by Mike | August 10, 2007 3:53 AM
plz help me.
i am worried about the concept of reflection.the points you mentioned about reflection understand but the code is confusing for me .i can't understand it.
Posted by maira | August 29, 2007 1:17 AM
Java offers the ability to override the ClassLoader and that's a beautiful idea not offered by most VMs. I don't think reflection particularly is beautiful in Java, given that the Java runtime is already dynamically typed. You can do similar stuff in Python and even more being purely interpreted.
On programming language "reflection", let me direct your attention to Partial Evaluation and even more on Turchin's work and its derivatives. I'm not talking about "reflection" in your sense but in a deeper sense: the ability of a programming language to transform itself! It's a research area, but some small examples have been published to create a compiler from an interpreter or on an automatically generated compiler compiler. And one can think of an syntax highlighter (or an IDE's plugin generator) derived from an interpreter modified by a semantic transformer. That's "wow!".
Posted by Carlos | December 19, 2007 8:28 PM