Ich bin mir nicht ganz sicher, ob ich die Frage verstehe, aber Java-Klassen enthalten bereits alles, was nötig ist, um über sie nachzudenken. Eine .class-Datei ändert sich nicht basierend auf ihrer Verwendung.
Edit 1: Bereitstellung einiger konkreter Beispiele zur besseren Unterscheidung der Art von "Reflexion", über die wir sprechen.
Beispiel:
class Foo {
public void bar() {
System.out.println("Hello, world.");
}
}
// Conventional calling
Foo f = new Foo();
foo.bar();
// Reflection based callling
Class fooClass = Class.forName("Foo");
Method m = fooClass.getMethod("bar", null);
Object f = fooClass.newInstance();
m.invoke(m, null);
Im herkömmlichen calling Fall Foo.class und eines seiner direkten Klasse Abhängigkeiten geladen. Bar wird ausgeführt. Die Zeichenfolgen "Foo" und "bar" wurden bereits als Teil der aufrufenden Klasse interniert, da der Byte-Code Strings verwendet, um die Klassen und Methoden zur Laufzeit aufzulösen. (eigentlich "bar" wird die volle Methodensignatur also eigentlich länger als nur "bar" sein)
Im Reflektionsfall passiert genau das Gleiche. Die einzige zusätzliche geladene Klasse ist Method.class. Das sollte der einzige Einfluss auf die Größe der Dauerwelle sein.
Der letztere Fall hat Auswirkungen auf die Leistung. Das Methoden-Lookup ist relativ teuer, daher ist es ratsam, Methodenobjekte im Cache zu speichern. Der Aufruf der zusätzlichen Methode zum Aufrufen hat eine geringe Auswirkung auf die Leistung, da es sich um einen zusätzlichen Methodenaufruf handelt. Hotspot wird Probleme haben, durch diesen Anruf zu optimieren ... zumindest mehr als normal. JITing passiert genau gleich.
Edit 2: einige zusätzliche Objekte Anbetracht dessen, dass bei der Reflexion ...
java.lang.Class erstellen und Cache-Method-Objekte (oder Feldobjekte, etc.) beim Zugriff geladen werden. Diese werden in einer SoftReference zwischengespeichert und daher zurückgewonnen, wenn die Speichernutzung dies erfordert.
Die Initialisierung dieser Objekte bedeutet jedoch, dass zusätzliche interne Strings von der VM geladen werden können, um die Erstellung dieser Method-Objekte zu unterstützen. Meine Vermutung ist, dass diese Strings wahrscheinlich bereits Teil des konstanten Pools der reflektiven Klasse waren, aber es ist möglich, dass dies nicht der Fall ist. So oder so, es ist ein einmaliger Treffer pro Methode pro Klasse, pro Feld pro Klasse, etc .. Greifen Sie auf die Methoden zu, Sie erhalten mindestens alle Namen für diese Methoden interniert. Greifen Sie auf die Felder zu, Sie erhalten die Namen dieser Felder interniert.
Was ich glaube, dass Sie dort sehen, ist das Internieren des gesuchten Namens, so dass '==' für die bereits intern gespeicherten Methodennamen verwendet werden kann. (Nicht überzeugt, dass das eine großartige Idee ist.) Im Gesicht kann Reflexion manchmal (manchmal) Klassen erzeugen. –
(Diese intern gespeicherten Strings sind GCable mit einem vollständigen Speicherbereinigungszyklus, eine gute Implementierungsqualität vorausgesetzt.) –
@Tom, können Sie ein einzelnes Beispiel angeben, in dem eine Klasse aufgrund von Reflektion erstellt wird? Ich versuche nicht, ein Schmerz zu sein, ich würde wirklich gerne von diesen Fällen wissen, da ich noch nie einen gesehen habe. – PSpeed