Oleg has posted 1 posts at DZone. View Full User Profile

About Reflection…

09.15.2010
| 7115 views |
  • submit to reddit

I never thought that will be faced with the need to write code that analyzes itself, but recently it happened. It should be noted that many developers do not use this method under any circumstances ... But it turned out that this code is incredibly flexible. Why?

Writing such a code has led me to release the following features:

  1. Self-analysis enables you to create multiple configurations at the level of code that makes the system flexible and modular.
  2. Having defined the interface (I do not mean Java interfaces) of the analyzed classes, you do not need to make any (!) changes in the code. Maybe you just you want to use annotations, which still remains a very flexible solution. ;)
  3. We get the independence of code from the existence and correctness of CDI. Of course, if you have correctly written the analyzing code...
  4. The code's logic cuts a lot of extra code that validates the use of dependency.
  5. And the most attractive, that it becomes possible to create a common interface to exchange parameters! You no longer need to think and worry about the number of parameters in the called method, you simply create a special object, the properties of which method will be determined.

The advantages are very attractive to me, but maybe they are insignificant for other developers because of the obvious problems:

  1. It is very difficult to determine the rules of the code analysis in the project. 
  2. It is difficult to unify these rules for the allocation of the universal functionality.
  3. Exchanging interface parameters is not always possible to unify even in any one module in the project without unnecessary complications in the architecture.

Solving these problems may leads to a very convenient framework, some of the makings of a functional already exist in specialized libraries (Spring Forms, Hibernate).

With all the charms that I found for myself in such an approach, you should be extremely careful with the performance ... Self-examination greatly slows down the system, so the use of reflection is necessary only when the gains from such an analysis (eg, cutting off unnecessary computations) will be significantly greater than the losses from the introspection.

Published at DZone with permission of its author, Oleg Tsarev.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

And Bod replied on Wed, 2010/09/15 - 11:44am

Reflection and introspection, if done superficially are about 10x slower than the "normal" way. Even if you go through all the hoopla of caching constructors classes and annotations its still 4x slower. And doing the latter kindda defeats the purpose of "simplifying code through reflection". Why don t u try harder for a better solution? Like if you need a variable number of arguments in a method call, use varargs.

RIchard replied on Wed, 2010/09/15 - 2:50pm

"Self-analysis enables you to create multiple configurations at the level of code that makes the system flexible and modular." . Ahh yes, but potatoes are French for fried chicken after March! :)


So, using reflection in a standard process at runtime will cause a bottleneck in a running system. That said, it's ok to do something like; loading Methods of a class into a collection (stack) at "load time" the penalty is minimized. However, if you go back to the Class.getMethod well, every time you need access, you will assassinate performance and may cause all sorts of GC issues inadvertently.


Byte-code analysis is also a great way to work with abstract code, without effecting runtime ops. Check out BCEL or ASM. If you prefer a more flexible approach, javassist is an incredibly powerful+simple library, that lets you create new classes, on the fly and insert methods as well as modify existing ones. This class works at both runtime and compiled byte-code levels, with emphasis on the runtime aspects where as the others BCEL and ASM are focused on byte-code.


As for frameworks that use reflective methods, every AOP (aspect oriented programming) frame relies on the above mentioned to generate and optimize code for their constituency.


Happy Hacking!
http://www.csg.is.titech.ac.jp/~chiba/javassist/
http://asm.ow2.org/
(BCEL comes with JDK 6) Project page: http://jakarta.apache.org/bcel/

Liam Knox replied on Wed, 2010/09/15 - 5:00pm in response to: And Bod

I think this performance argument is just old hat. Some things you cannot simply do without reflection. For example, Spring IoC or Freemarker markup both could never of existed which would indeed be a bit of a bummer

Also your metrics here mean absolutely nothing without some context. In realism what is the difference between 1ms to 4ms if your application spends the next 99.9% of total time in I/O calls?

Please drop this dated argument unless you have a specific context.

Oleg Tsarev replied on Thu, 2010/09/16 - 3:16am in response to: And Bod

My last sentence in the article:
"Self-examination greatly slows down the system, so the use of reflection is necessary only when the gains from such an analysis (eg, cutting off unnecessary computations) will be significantly greater than the losses from the introspection."

I am not encouraged to use reflection wherever possible. I'm talking about the fact that reflection can deliver the much more labor-intensive and inefficient solutions.

For example, in one of the projects being developed on about 9 years, there are many different "modules". Architecture of the project is optimal, but not always new functionality makes sense to build in this architecture due to falling productivity. And performance is not the code itself, as a logical chain challenges. In this case, reflection allowed to make a decision in 11 times more productive. The complexity of the architecture and even its small connection do not necessarily allow you productive to introduce new features with classic approaches.

In this case, autosubstitution method parameters - it is a consequence and not the result of the use of reflection in the project.

Oleg Tsarev replied on Thu, 2010/09/16 - 3:15am in response to: RIchard

Thanks for the links, but I do not quite understand why you do not like my argument about the independent configurations? Modularity pronounced when the configuration carried by the various bundles, and in this case the system becomes really incredibly flexible.

In addition, it should be noted that the bottlenecks in application arise when thoughtless use of all what is possible). All should be used judiciously.

Reflection allows you to customize the interaction with the models initially inconsistent required interfaces. Perhaps a dubious argument, but the stability of this system grows up and the requirements for external "modules" sharply reduced.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.