6

Today I was wondering why frameworks like `Hibernate use reflection instead of code generation (for example using libraries like BCEL or ASM) during compilation/application startup.

Is it because of historical reasons (when Hibernate was being written there was no such library available that would allow byte code generation on the fly) and now everybody uses this approach?

I would assume that the approach with generated code would be faster then the one that uses reflection.

Andna
  • 6,539
  • 13
  • 71
  • 120
  • 1
    Reflection is not that slow, especially in the context of I/O - database/file access will be several orders of magnitude slower that the performance hit due to reflection. – assylias Apr 07 '14 at 07:11
  • Yeah, you are probably right. I just asked this question because I was curious about the decision to use reflection. After so many years of JVM I believe there are many optimizations that speed up the reflection compared to first release of `Java`. – Andna Apr 07 '14 at 08:38

1 Answers1

7

Right, Hibernate could likely benefit from code generation, though the profit might not be as big as you suppose.

  1. First of all, Reflection uses bytecode generation under the hood and it is not too slow.
  2. You can't do some sort of things using bytecode generation only. E.g. reflection allows you to access private fields and to invoke private methods, while it is not possible with bytecode generation (unless you use certain non-portable hacks).
Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247
  • Ad. 1 - do you have any source on this (code generation I mean)? I never really read how reflection works under the hood. I would be glad if you could point me to some article. Ad. 2 - true, point for reflection – Andna Apr 07 '14 at 08:35
  • 3
    Have a look at [Reflection sources](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/43cb25339b55/src/share/classes/sun/reflect) in OpenJDK, `MethodAccessorGenerator.java` in particular. In short, `java.lang.Method` has an accessor to which invocations are delegated. First 15 calls of `Method.invoke()` are executed through a native call by JVM (see `NativeMethodAccessorImpl.java`). Then, as soon as `sun.reflect.inflationThreshold` is reached (15 by default), bytecode generation runs and `NativeMethodAccessorImpl` is replaced with dynamically generated Java accessor. – apangin Apr 07 '14 at 09:14
  • Thanks for linking the relevant sources. – Andna Apr 07 '14 at 09:30