2014-04-07 18 views
6

Heute habe ich mich gefragt, warum Frameworks wie `Hibernate 'Reflection anstelle von Codegenerierung (zum Beispiel mit Bibliotheken wie BCEL oder ASM) beim Kompilieren/Start der Anwendung verwenden.Java reflection vs code generation

Ist es aus historischen Gründen (wenn Hibernate geschrieben wurde, gab es keine solche Bibliothek zur Verfügung, die Byte-Code-Generierung im laufenden Betrieb erlauben würde) und jetzt jeder nutzt diese Methode?

Ich würde annehmen, dass der Ansatz mit generiertem Code schneller wäre als der, der Reflexion verwendet.

+1

Die Reflexion ist nicht so langsam, besonders im Zusammenhang mit I/O - Datenbank/Dateizugriff wird mehrere Größenordnungen langsamer, dass die Leistung aufgrund der Reflexion zu treffen. – assylias

+0

Ja, wahrscheinlich hast du recht. Ich habe diese Frage nur gestellt, weil ich neugierig war auf die Entscheidung, die Reflexion zu verwenden. Nach so vielen Jahren von JVM glaube ich, dass es viele Optimierungen gibt, die die Reflexion im Vergleich zur ersten Veröffentlichung von 'Java' beschleunigen. – Andna

Antwort

6

Richtig, Hibernate könnte wahrscheinlich von der Codegenerierung profitieren, obwohl der Gewinn möglicherweise nicht so groß ist, wie Sie annehmen.

  1. Zuerst verwendet Reflection Bytecode-Generierung unter der Haube und es ist nicht zu langsam.
  2. Sie können keine Dinge nur mit Bytecode-Generierung tun. Z.B. reflection ermöglicht es Ihnen, auf private Felder zuzugreifen und private Methoden aufzurufen, während dies bei der Bytecode-Generierung nicht möglich ist (es sei denn, Sie verwenden certain non-portable hacks).
+0

Anzeige. 1 - Haben Sie eine Quelle (Code Generation meine ich)? Ich lese nie wirklich, wie Reflektion unter der Haube funktioniert. Ich würde mich freuen, wenn Sie mich auf einen Artikel hinweisen könnten. Anzeige. 2 - true, Reflektionspunkt – Andna

+2

Sehen Sie sich [Reflection sources] (http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/43cb25339b55/src/share/classes/sun/reflect) an OpenJDK, insbesondere 'MethodAccessorGenerator.java'. Kurz gesagt, 'java.lang.Method' hat einen Accessor, an den Aufrufe delegiert werden. Die ersten 15 Aufrufe von 'Method.invoke()' werden über einen nativen Aufruf von JVM ausgeführt (siehe 'NativeMethodAccessorImpl.java'). Sobald "sun.reflect.inflationThreshold" erreicht ist (standardmäßig 15), wird Bytecode generiert und 'NativeMethodAccessorImpl' wird durch dynamisch generierten Java-Accessor ersetzt. – apangin

+0

Danke für die Verknüpfung der relevanten Quellen. – Andna