views:

85

answers:

3

Java's reflection API is obviously a very powerful tool, but not particularly object-oriented. What are some situations where it is appropriate (and conversely, inappropriate) to use reflection?

+2  A: 

I would suggest taking a look at the book: Java Reflection in Action.

It is very good, it is detailed, and practically a complete reference about this advanced concept.

Also it's much more than we could possibly explain here, with scenarios, usages and concepts that first come clear when you simply read it :).

A. Ionescu
+3  A: 

In my opinion...

Appropriate (clean):

  • Instantiating root of a dynamically-loaded implementation, such as an applet.
  • Use of Proxy to create a proxy or a mock implementation (may be better at compile time).
  • Implementing interpreters that allow unrestricted access to the Java libraries. (Note, from a security perspective the interpreted code now has the effective privileges as the interpreter - can be kind of dangerous.)

Appropriate hacks:

  • Circumventing Java language access controls in third party code where you absolutely have to.
  • Implementing a "cross-cutting concern" such as persistence.
  • Removing static dependencies that load classes causing slower start up.

Inappropriate:

  • General circumventing Java language access controls (includes testing).
  • Anything the relies upon Java language access rights given by the particular reflection-calling class.
  • Anywhere where implementing an interface would work.

Generally reflection is much easier than generating source which is much easier than creating bytecode.

Tom Hawtin - tackline
I like the comment on interfaces; I've run into some code I was maintaining recently where I think this was the case.
Feanor
+1  A: 

Like with any technology, the common sence should be the driver in determining which usage is appropriate. Not "patterns", blocking brain's ability of thinking.

Don't think of reflection as of "technology". It is just a metadata object associated with any datatype and available in runtime. Simple object, implemented in optimum possible way (just think how you would implement it and you will most likely guess the actual implementation).

From just simple considerations, it is clear that all methods on Class/Method/Field of type get-something-by-name cause a map/index lookup every time they are invoked, so this operation is somewhat worth doing just once in the application life. But once obtained, the performance of method.invoke(object, args) is pretty much the same as that of object.method(args), because it introduces only one more level of indirection, not involving any additional lookups.

Examples where I would use reflection based approach:

  • initialize/copy/serialize/print bean's properties by name, this task arises in most of business applications and, once you use a dynamic programming (meaning do name-based lookups only once to initialize converters/loaders and then apply the same converter along the application lifetime) adds not much overhead but adds an exellent flexibility to the software (see commons-beanutils, spring dependency injection).

  • transaction/session/authorization/metrics/mock proxies (using Dynamic Proxy API from JDK)

  • convenient alternative to XSD eliminating XML parser (using JPA/JAXB/WS/JAXB and any other annotations) to keep supplementary information about how the object shall persist itself, what GUI labels shall be displayed for each field, etc. (see jax-ws, hibernate)

I can't think out an example where I woudn't use reflection, just don't use it where metadata-based solution is not optimal (from just analyzing what metadata object is).

bobah