2014-04-07 25 views
6

Oggi mi chiedevo perché framework come Hibernate usano il reflection anziché la generazione del codice (ad esempio usando librerie come BCEL o ASM) durante l'avvio della compilation/dell'applicazione.Java reflection vs code generation

È a causa di motivi storici (quando Hibernate veniva scritto non esisteva alcuna libreria disponibile che consentisse la generazione di codice byte al volo) e ora tutti utilizzano questo approccio?

Suppongo che l'approccio con codice generato sia più veloce di quello che utilizza la riflessione.

+1

La riflessione non è così lenta, specialmente nel contesto di I/O: l'accesso al database/file sarà più lento di diversi ordini di grandezza a causa della riflessione. – assylias

+0

Sì, probabilmente hai ragione. Ho appena fatto questa domanda perché ero curioso della decisione di usare la riflessione. Dopo tanti anni di JVM credo ci siano molte ottimizzazioni che accelerano la riflessione rispetto alla prima versione di 'Java'. – Andna

risposta

6

Right, Hibernate potrebbe probabilmente beneficiare della generazione del codice, anche se il profitto potrebbe non essere grande come si suppone.

  1. Innanzitutto, Riflessione utilizza la generazione di bytecode sotto il cofano e non è troppo lento.
  2. Non è possibile eseguire alcune operazioni utilizzando solo la generazione bytecode. Per esempio. reflection consente di accedere a campi privati ​​e di invocare metodi privati, mentre non è possibile con la generazione di bytecode (a meno che non si usi certain non-portable hacks).
+0

Ad. 1 - hai qualche fonte su questo (generazione di codice intendo)? Non ho mai veramente letto come funziona la riflessione sotto il cofano. Sarei felice se tu potessi indicarmi un articolo. Ad. 2 - true, point for reflection – Andna

+2

Dai un'occhiata a [Fonti di riflessione] (http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/43cb25339b55/src/share/classes/sun/reflect) in OpenJDK, 'MethodAccessorGenerator.java' in particolare. In breve, 'java.lang.Method' ha una funzione di accesso a cui sono state delegate le chiamate. Le prime 15 chiamate di 'Method.invoke()' sono eseguite tramite una chiamata nativa da JVM (si veda 'NativeMethodAccessorImpl.java'). Quindi, non appena viene raggiunto 'sun.reflect.inflationThreshold' (15 per impostazione predefinita), le esecuzioni di generazione di codice e' NativeMethodAccessorImpl' vengono sostituite con accessor Java generato dinamicamente. – apangin

+0

Grazie per aver collegato le fonti pertinenti. – Andna