Was ist die Verwendung von Reflektion in Java / C # usw. [duplizieren]

8

Ich war nur neugierig, warum sollten wir zuerst Reflexion verwenden?

%Vor%

Wir können einfach ein Objekt erstellen und die Methode der Klasse aufrufen, aber warum machen wir das mit den Funktionen forName, newInstance und getMthod?

Um alles dynamisch zu machen?

    
zengr 21.03.2010, 20:11
quelle

9 Antworten

27

Einfach gesagt: weil man manchmal die Teile "Foo" oder "Hallo" zur Kompilierzeit nicht kennt.

Die meiste Zeit, die Sie tun wissen das, es lohnt sich also nicht, die Reflexion zu verwenden. Nur gelegentlich, aber nicht - und an diesem Punkt können Sie sich nur noch auf Reflexion konzentrieren.

Als Beispiel können Sie mit Protokollpuffern Code erstellen, der entweder vollständigen statisch getippten Code zum Lesen und Schreiben von Nachrichten enthält, oder diesen erzeugt gerade genug, so dass der Rest durch Reflektion erfolgen kann: Im Reflektionsfall muss der Lade- / Speicher-Code Eigenschaften über Reflektion bekommen und setzen - er kennt die Namen der beteiligten Eigenschaften aufgrund des Message Descriptors. Dies ist viel (viel) langsamer, führt aber dazu, dass wesentlich weniger Code generiert wird.

Ein weiteres Beispiel wäre die Dependency Injection, bei der die Namen der für die Abhängigkeiten verwendeten Typen oft in Konfigurationsdateien bereitgestellt werden: Das DI-Framework muss dann Reflektion verwenden, um alle beteiligten Komponenten zu konstruieren und Konstruktoren und / oder Eigenschaften entlang der Weg.

    
Jon Skeet 21.03.2010, 20:13
quelle
4

Sie wird immer dann verwendet, wenn Sie (= Ihre Methode / Ihre Klasse) zur Kompilierzeit nicht wissen, welcher Typ instanziiert werden soll oder welche Methode aufgerufen werden soll.

Außerdem verwenden viele Frameworks Reflektion, um Ihre Objekte zu analysieren und zu verwenden. Zum Beispiel:

  • hibernate / nhibernate (und jeder objektrelationale Mapper) verwendet reflection, um alle Eigenschaften Ihrer Klassen zu prüfen, so dass sie in der Lage sind, sie zu aktualisieren oder sie beim Ausführen von Datenbankoperationen zu verwenden
  • Vielleicht möchten Sie es konfigurierbar machen, welche Methode einer benutzerdefinierten Klasse standardmäßig von Ihrer Anwendung ausgeführt wird. Der konfigurierte Wert ist String , und Sie können die Zielklasse abrufen, die Methode mit dem konfigurierten Namen abrufen und sie aufrufen, ohne sie zur Kompilierungszeit zu kennen.
  • Analyseanmerkungen werden durch Reflexion
  • gemacht
Bozho 21.03.2010 20:21
quelle
3

Eine typische Verwendung ist ein Plug-In-Mechanismus, der Klassen (normalerweise Implementierungen von Schnittstellen) unterstützt, die zur Kompilierungszeit unbekannt sind.

    
deamon 21.03.2010 20:16
quelle
3

Sie können die Reflektion zum Automatisieren von Prozessen verwenden, die sinnvollerweise eine Liste der Methoden und / oder Eigenschaften des Objekts verwenden. Wenn Sie jemals Zeit damit verbracht haben, Code zu schreiben, der in jedem der Felder eines Objekts die gleiche Sache macht - die offensichtliche Art, Daten zu speichern und zu laden, funktioniert oft so -, dann könnte Reflektion automatisch für Sie tun.

Die häufigsten Anwendungen sind wahrscheinlich diese drei:

  • Serialisierung (siehe z. B. .NET XmlSerializer )
  • Generierung von Widgets zum Bearbeiten von Objekteigenschaften (z. B. Xcode's Interface Builder, .NET-Dialogdesigner)
  • Fabriken, die Objekte mit beliebigen Abhängigkeiten erstellen, indem sie die Klassen für Konstruktoren untersuchen und geeignete Objekte bei der Erstellung bereitstellen (z. B. jedes Abhängigkeitsinjektions-Framework)
please delete me 21.03.2010 20:20
quelle
2

Mit Reflection können Sie sehr einfach Konfigurationen schreiben, die Methoden / Felder im Text detailliert beschreiben, und das Framework, das diese verwendet, kann eine Textbeschreibung des Feldes lesen und das echte entsprechende Feld finden.

z.B. Mit JXPath können Sie Objekte wie folgt navigieren:

%Vor%

Also sucht JXPath nach einer Methode getCompany() (entsprechend company ), einem Feld in dem name usw. genannt wird.

Sie finden dies in vielen Frameworks in Java, z. JavaBeans, Spring etc.

    
Brian Agnew 21.03.2010 20:20
quelle
1

Dies ist nützlich für Dinge wie Serialisierung und objektrelationales Mapping. Sie können eine generische Funktion schreiben, um ein Objekt zu serialisieren, indem Sie reflection verwenden, um alle Eigenschaften eines Objekts abzurufen. In C ++ müssten Sie für jede Klasse eine separate Funktion schreiben.

    
dan04 21.03.2010 20:19
quelle
1

Ich habe es schon früher in einigen Validierungsklassen verwendet, wo ich eine große, komplexe Datenstruktur im Konstruktor übergeben habe und dann eine Zillion (ein paar hundert wirklich) Methoden ausgeführt habe, um die Validität der Daten zu überprüfen. Alle meine Validierungsmethoden waren privat und boolesch zurückgegeben, also habe ich eine "validate" -Methode erstellt, die man aufrufen konnte, die Reflektion verwendete, um alle privaten Methoden in der Klasse aufzurufen, als Booleans zurückgegeben.

Dies machte die Validierungsmethode prägnanter (musste nicht jede kleine Methode aufzählen) und garantierte, dass alle Methoden ausgeführt wurden (zB schreibt jemand eine neue Validierungsregel und vergisst, sie in der Hauptmethode aufzurufen).

Nach der Umstellung auf Reflektion habe ich keinen nennenswerten Leistungsverlust bemerkt und der Code war leichter zu pflegen.

    
Windle 21.03.2010 20:31
quelle
0

Manchmal müssen Sie ein Objekt der Klasse on-fly oder von einem anderen Ort erstellen, nicht von einem Java-Code (z. B. jsp). Zu dieser Zeit ist Reflexion nützlich.

    
Parth 21.03.2010 20:39
quelle
0

zusätzlich zu Jons Antwort, eine andere Verwendung ist in der Lage zu sein, "Ihren Zeh im Wasser zu tauchen", um zu testen, ob eine gegebene Einrichtung in der JVM vorhanden ist.

Unter OS X sieht eine Java-Anwendung besser aus, wenn einige von Apple bereitgestellte Klassen aufgerufen werden. Der einfachste Weg, um zu testen, ob diese Klassen vorhanden sind, besteht darin, zuerst mit Reflektion zu testen

    
quelle

Tags und Links