I don't get it. Why is reflection complex?
Granted, the [Java] reflection APIs declare all sorts of silly, checked exceptions but once I wrap those in my own methods to clean things up, I don't find anything about the API complex.
Yes, the stack trace can sometimes be hard to decipher, but I find that I hardly use stack traces for debugging anyway. The VisualAgeJava
debugger can stop on any given exception, don't other debuggers do the same thing?
Reflection requires a programmer to work in an non-restrictive, abstract layer. This is a degree more complex than manipulating objects directly.
But remember: It is one degree more complex. But it's only one degree more complex.
So don't run away screaming just because reflection might be involved:
You requirements might be one degree more complex than can reasonably be accomplished with static non data driven code.
I don't buy the argument that reflection adds complexity. Other than syntax issues, how is reflection in Java any more abstract than message sends to dynamically typed objects in Smalltalk? In discussions of static typing versus dynamic typing, I haven't seen the issue of complexity come up.
Typing and reflection are two very distinctly different things. Dynamically typed languages, such as Ruby, can have reflection too, so it is not merely a way to make a strongly typed language into a dynamic one. If you look at simple examples or the API's for reflection, they are not complex, but IME the complexity arises when reflection is applied to a particularly difficult problem. I'm not saying that reflection shouldn't be used. It is often the only way to effectively tackle a problem.
In Java, reflection makes Exception handling a pain in the ass. Normally, correct expectations regarding exception-handling are dealt with by the compiler, which uses what it knows about method signatures to complain if you aren't handling exceptions that might be thrown. But if you invoke() a Method, you have no control over what sort of Exception that Method.invoke() might throw, so fine-grained handling of it is extremely difficult.
One solution is to require that every method intended to be called through reflection cannot throw an Exception other than a R
untimeException to bring the whole thing to its knees. It's a kludge, but if use of reflection is contained to a few parts of the code, it can work.
In my experience, reflection becomes more complex when you want performance out of it and to achieve that you have to cache methods etc.
This adds more code and more complexity to handle. -- VhIndukumar
Reflection in Perl is elegant, simple, efficient, unobtrusive. It actually makes things easier. If you're complaining about how Java's reflection system is hopeless, realize that it's Java; get over it. -- SunirShah
In a system that uses reflection you can't be sure that a method is unused. Even though the method name isn't visible anywhere the name can be created as a string and then used to call the method. This can get in the way of both automatic refactoring tools and human understanding of the code.
The following pattern makes reflection straightforward. Use reflection to create an instance. Cast the instance into an interface. Then call the interface methods without using reflection. This approach handles the only reflection requirement that I've encountered: supporting multiple adaptors.
This sounds similar to the only real thing I've used reflection in CeeSharp for: pluggable types. I use reflection to find all classes inherited from some base class, and allow the user to pick which ones to use in which situations. Reflection is also used to construct an instance of the chosen class, and then it's just passed around as a reference of the base class type (all methods that get called from outside are virtual). This way, if I want to add a new option that the user can select, all I have to do is create a new class that inherits from the base, and code its inherited methods appropriately - no other code has to be changed. Of course I could have used some sort of RegistrationPattern? instead, but I thought it'd be tidier this way.
See also: JavaReflectionNoPanacea