Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I don't know why, but I always feel like I am "cheating" when I use reflection - maybe it is because of the performance hit I know I am taking.

Part of me says, if it is part of the language you are using and it can accomplish what you are trying to do, then why not use it. The other part of me says, there has to be a way I can do this without using reflection. I guess maybe it depends on the situation.

What are the potential issues I need to look out for when using reflection and how concerned should I be about them? How much effort is it worth spending to try to find a more conventional solution?

share|improve this question
2  
I guess it depends on the language and the environment. Some support it, even encourage it. Sometimes when working in Java I have wished for better reflection support. –  FrustratedWithFormsDesigner Aug 15 '11 at 14:16
16  
Well, I guess it's not so hard to dinstguish between "cheating reflection" and a valid use of it: When you inspect private members or use it to call private methods (to work around interfaces), then it's very likely cheating. When you use it to interact with types you have otherwise no knowledge about, then it's probably ok (databinding, proxies etc.). –  Falcon Aug 15 '11 at 15:05
    
What language are you using? Brainfuck does not have reflection and Python is just different. –  Job Aug 15 '11 at 17:08
    
I also never understood why it is allowed to access private methods through reflection. According to my intuition it should be forbidden. –  Giorgio Aug 15 '11 at 21:06
2  
Hard to believe that such a poorly-worded question got 27 upvotes without any editing. –  Aaronaught Aug 16 '11 at 3:38
add comment

12 Answers

up vote 42 down vote accepted

No, it's not cheating - it is a way to solve problems in some programming languages.

Now, it is often not the best (cleanest, simplest, easiest to maintain) solution. If there is a better way, use that one indeed. However, sometimes there isn't. Or if there is, it is just so much more complex, involving a lot of code duplication etc. which makes it infeasible (difficult to maintain in the long run).

Two examples from our current project (Java):

  • some of our testing tools use reflection to load configuration from XML files. The class to be initialized has specific fields, and the config loader uses reflection to match the XML element named fieldX to the appropriate field in the class, and to initialize the latter. In some cases, it can build a simple GUI dialog box out of the identified properties on the fly. Without reflection, this would take hundreds of lines of code across several applications. So reflection helped us put together a simple tool quickly, without much fuss, and enabled us to focus on the important part (regression testing our web app, analysing server logs, etc.) rather than the irrelevant.
  • one module of our legacy web app was meant to export/import data from DB tables to Excel sheets and back. It contained a lot of duplicated code, where of course the duplications were not exactly the same, some of them contained bugs etc. Using reflection, introspection and annotations, I managed to eliminate most of the duplication, cutting down the amount of code from over 5K to below 2.4K, while making the code more robust and way easier to maintain or extend. Now that module ceased to be a problem to us - thanks to the judicious use of reflection.

The bottom line is, like any powerful tool, reflection too can be used to shoot yourself in the foot. If you learn when and how (not) to use it, it can bring you elegant and clean solutions to otherwise difficult problems. If you abuse it, you can turn an otherwise simple problem into a complex and ugly mess.

share|improve this answer
6  
+1 Reflection is incredibly useful for data import/export when you have intermediate objects for conversion reasons. –  Ed Woodcock Aug 15 '11 at 14:34
1  
It's also incredibly useful in data-driven apps - instead of using a massive stack of if (propName = n) setN(propValue);, you can name your (i.e.) XML tags the same as your code properties and run a loop over them. This method also makes it far simpler to add properties later. –  Michael K Aug 15 '11 at 15:54
    
Reflection is used heavily in Fluent interfaces, like FluentNHibernate. –  Scott Whitlock Aug 15 '11 at 19:13
1  
@Michael: Until you decide to rename one of those properties in the class and find that your code explodes. If you don't need to maintain comparability with things your program generates, that's fine, but I suspect that's not most of us. –  Billy ONeal Aug 15 '11 at 19:44
1  
@Billy, I didn't mean to contradict you, I agree with what you wrote. Although, the example you bring is IMHO more a subcase of the general rule "avoid changing public interfaces". –  Péter Török Aug 16 '11 at 6:42
show 2 more comments

It's not cheating. But it is usually a bad idea in production code for at least the following reasons:

  • You lose compile-time type safety - it's helpful to have the compiler verify that a method is available at compile time. If you are using reflection, you'll get an error at runtime which might affect end users if you don't test well enough. Even if you do catch the error, it will be be more difficult to debug.
  • It causes bugs when refactoring - if you are accessing a member based on it's name (e.g. using a hard-coded string") then this won't get changed by most code refactoring tools and you'll instantly have a bug, which might be quite hard to track down.
  • Performance is slower - reflection at runtime is going to be slower than statically compiled method calls/variable lookups. If you're only doing reflection occasionally then it won't matter, but this can become a performance bottleneck in cases where you are making calls via reflection thousands or millions of times per second. I once got a 10x speedup in some Clojure code simply by eliminating all reflection, so yes this is a real issue.

I'd suggest limiting the use of reflection to the following cases:

  • For quick prototyping or "throwaway" code when it is the simplest solution
  • For genuine reflection use cases, e.g. IDE tooling that allows a user to examine the fields / methods of an arbitrary object at runtime.

In all other cases I'd suggest figuring out an approach that avoid reflection. Defining an interface with the appropriate method(s) and implementing it on the set of classes you want to call the method(s) on is usually sufficient to solve most simple cases.

share|improve this answer
    
+1 -- there are several use cases for reflection; but most of the time I see programmers using it they are papering over designs with serious flaws. Define interfaces and attempt to remove dependency on reflection. Just like GOTO, it has its uses, but most of them aren't good. (Some of them are good, of course) –  Billy ONeal Aug 15 '11 at 19:43
3  
Bear in mind that the above points may or may not apply to your favourite language. For instance, reflection has no speed penalty in Smalltalk, nor do you lose compile-time safety, because computation is entirely late bound. –  Frank Shearar Aug 15 '11 at 19:47
    
Reflection in D don't has drawback you mention. So I would argue that you re blaming implementation in some languages more tha refelection itself. I don't know much about smalltalk, but according to @Frank Shearar, it doesn't have thoses drawback too. –  deadalnix Aug 15 '11 at 20:32
1  
@deadalinx: To which downside do you refer? There are several in this answer. The performance issue is the only thing that's language dependant. –  Billy ONeal Aug 15 '11 at 20:38
    
I should add that the second issue - bugs caused during refactoring - is probably the most serious. In particular, relying on something having a particular name breaks instantly when that thing's name changes. The errors thus caused may be less than informative, unless you're very careful. –  Frank Shearar Aug 16 '11 at 8:06
add comment

Reflection is just another form of meta-programming, and just as valid, as the type-based parameters that you see in most languages these days. Reflection is powerful and generic, and reflective programs are a high order of maintainability (when used correctly, of course) and more so than purely object-orientated or procedural programs. Yes, you pay a performance price- but I'd gladly go for a slower program that's more maintainable in many, or even most, cases.

share|improve this answer
2  
+1, this helps me understand what reflection is. I'm a C++ programmer, and so I've never really grokked reflection. This helps. (Though I confess that from my perspective, Reflection seems like an attempt at reconciling a deficiency in the language. We C++ guys use templates for that. So I suppose you could say the same of that. :) –  greyfade Aug 15 '11 at 16:42
4  
Re performance - in some cases, you can use the reflection API to write back fully performance code. For example, in .NET you can write IL into the current app - hence your "reflection" code can be just as fast as any other code (except you can remove a lot of the if/else/whatever, as you've already figured out the exact rules) –  Marc Gravell Aug 15 '11 at 18:42
    
@greyfade: In a sense, templates are doing compile-time-only reflection. Being able to do it at runtime has the advantage of allowing powerful capabilities to be constructed in the application without having to recompile. You trade performance for flexibility, an acceptable tradeoff more of the time than you might expect (given your C++ background). –  Donal Fellows Aug 16 '11 at 10:18
add comment

Surely it all depends on what are you trying to achieve.

For example, I wrote a media checker application that uses dependency injection to determine what sort of media (MP3 files or JPEG files) to check. The shell needed to display a grid containing the pertinent information for each type, but it had no knowledge of what it was going to display. This is defined in the assembly that reads that type of media.

Therefore I had to use reflection to get the number of columns to display and their types and names so I could set the grid up correctly. It also meant that I could update the injected library (or create a new one) without changing any other code or configuration file.

The only other way would have been to have a configuration file that would need to be updated when I switched the type of media being checked. This would have introduced another point of failure for the application.

share|improve this answer
1  
"Surely it all depends on what are you trying to achieve." +1 –  DaveShaw Aug 15 '11 at 19:26
add comment

Reflection is fantastic for building tools for developers.

As it allows your build environment to inspect the code and potentially generate the correct tools to manipulate/init inspect the code.

As a general programming technique it can be useful but is more brittle than most people imagine.

One really development use for reflection (IMO) is that it makes writing a generic streaming library very simple (as long as your class description never changes (then it becomes a very brittle solution)).

share|improve this answer
add comment

Reflection is an awesome tool if you are a library author, and thus have no influence over the incoming data. A combination of reflection and meta-programming can allow your library to work seamlessly with arbitrary callers, without them having to jump through hoops of code-generation etc.

I do try to discourage from reflection in application code, though; at the app layer you should be using different metaphors - interfaces, abstraction, encapsulation etc.

share|improve this answer
add comment

An alternative, in cases where the domain of the reflected classes is well-defined, is to use reflection along with other metadata to generate code, instead of using reflection at runtime. I do this using FreeMarker/FMPP; there are lots of other tools to choose from. The advantage to this is that you end up with "real" code that can easily be debugged, etc.

Depending on the situation, this can help you make a lot faster code - or just a lot of code bloat. It avoids the disadvantages of reflection:

  • loss of compile-time type safety
  • bugs due to refactoring
  • slower performance

mentioned earlier.

If reflection feels like cheating, it may be because you're basing it on a lot of guesswork that you're not sure of, and your gut is warning you that this is risky. Be sure to provide a way to enhance the metadata inherent in reflection with your own metadata, where you can describe all the quirks and special cases of the real-world classes you may encounter.

share|improve this answer
add comment

It totally depends. An example of something that would be hard to do without reflection would be to replicate ObjectListView. It also generates IL code on the fly.

share|improve this answer
add comment

It isn't cheating, but like any tool, it should be used for what it is intended to solve. Reflection, by definition, allows you to inspect and modify code through code; if that is what you need to do, then reflection is the tool for the job. Reflection is all about meta-code: Code that targets code (as opposed to regular code, which targets data).

An example of good reflection use is generic web service interface classes: A typical design is to separate protocol implementation from payload functionality. So then you have one class (let's call it T) that implements your payload, and another that implements the protocol (P). T is fairly straightforward: for every call you want to make, simply write one method that does whatever it is supposed to do. P, however, needs to map web service calls to method calls. Making this mapping generic is desirable, because it avoids redundancy, and makes P highly reusable. Reflection provides the means to inspect class T at runtime and call its methods based on strings passed into P through the web service protocol, without any compile-time knowledge of class T. Using the 'code about code' rule, one can argue that class P has the code in class T as part of its data.

However.

Reflection also gives you tools to get around restrictions of the language's type system - theoretically, you could pass all parameters as type object, and call their methods through reflections. Voilà, the language that is supposed to enforce strong static typing discipline now behaves like a dynamically typed language with late binding, only that the syntax is far more elaborate. Every single instance of such a pattern I've seen so far has been a dirty hack, and invariably, a solution within the language's type system would have been possible, and it would have been safer, more elegant, and more efficient in all regards.

A few exceptions exist, such as GUI controls that can be data-bound to various non-related types of data sources; mandating that your data implement a certain interface just so you can data-bind it isn't realistic, and neither is having the programmer implement an adaptor for each type of data source. In this case, using reflection to detect the type of data source and adjusting the data binding is a more useful choice.

share|improve this answer
add comment

One problem we have had with Reflection is when we added Obfuscation to the mix. All classes get new names and suddenly loading a class or function by its name stops working.

share|improve this answer
add comment

Reflection can achieve things that simply can't be done practically otherwise.

For example, consider how to optimize this code:

int PoorHash(char Operator, int seed, IEnumerable<int> values) {
    foreach (var v in values) {
        seed += 1;
        switch (char) {
            case '+': seed += v; break;
            case '^': seed ^= v; break;
            case '-': seed -= v; break;
            ...
        }
        seed *= 3;
    }
    return seed;
}

There's an expensive test smack in the middle of the inner loop, but extracting it requires rewriting the loop once for each operator. Reflection allows us to get performance on par with extracting that test, without repeating the loop a dozen times (and thereby sacrificing maintainability). Just generate and compile the loop you need on the fly.

I have actually done this optimization, although it was a bit more complicated of a situation, and the results were amazing. An order of magnitude improvement in performance and fewer lines of code.

(Note: I initially tried the equivalent of passing in a Func instead of a char, and it was slightly better, but not nearly the 10x reflection achieved.)

share|improve this answer
1  
The better optimization is to pass a functor instead. Will likely get inlined at runtime by the JIT compiler and is more maintainable than reflection. –  Billy ONeal Aug 15 '11 at 20:47
    
That would be more maintainable, and I actually try it first, but it wasn't fast enough. The JIT was definitely not inlining it, probably because in my case there was a second inner loop over the operations to perform. –  Strilanc Aug 16 '11 at 16:24
    
Also, I point out that what you've got there is really self modifying code, which isn't really reflection. One accesses it through reflection APIs in most languages which do support reflection, but it can be done just as simply in languages not supporting reflection (e.g. it would be possible in C++) –  Billy ONeal Aug 16 '11 at 17:20
    
I wanted to avoid the standard 'structural equality' example. Reflection is not necessary for self-modifying code, but it certainly helps. –  Strilanc Aug 18 '11 at 16:48
    
Not really. You can do that in non-reflection languages just fine. –  Billy ONeal Aug 18 '11 at 17:23
add comment

No way is it cheating... Rather, it empowers application servers to run the classes made by the user with the name of their choice, hence providing flexibility to the user, not cheating them.

And if you want to see the code of any .class file (in Java) then there are several decompilers available free of charge!

share|improve this answer
    
Decompilation isn't a reflection feature. –  Billy ONeal Aug 15 '11 at 20:49
    
yes, it is not... But i meant to say that if u feel like cheating while using reflection(which provide you details of any class in java) than u are wrong bcoz reflection is a very useful concept and if getting details of any class is what is concerning you than that can be done easily with any decompiler... –  ANSHUL JAIN Aug 16 '11 at 16:23
1  
Reflection is a useful concept in some cases, yes. But 99.9% of the time I see it being used I see it used to hack around a design error. –  Billy ONeal Aug 16 '11 at 17:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.