2558 Stimmen

Was ist Reflexion und warum ist sie nützlich?

Was ist Reflexion, und warum ist sie nützlich?

Ich interessiere mich besonders für Java aber ich gehe davon aus, dass die Grundsätze in jeder Sprache die gleichen sind.

49voto

Mendelt Punkte 35649

Nicht jede Sprache unterstützt Reflexion, aber die Prinzipien sind in der Regel die gleichen in Sprachen, die sie unterstützen.

Reflexion ist die Fähigkeit, über die Struktur Ihres Programms "nachzudenken". Oder noch konkreter. Man kann die Objekte und Klassen, die man hat, betrachten und programmatisch Informationen über die Methoden, Felder und Schnittstellen, die sie implementieren, zurückbekommen. Sie können auch Dinge wie Annotationen betrachten.

Sie ist in vielen Situationen nützlich. Überall dort, wo Sie in der Lage sein wollen, dynamisch Klassen in Ihren Code einzufügen. Viele objektrelationale Mapper verwenden Reflection, um Objekte aus Datenbanken instanziieren zu können, ohne im Voraus zu wissen, welche Objekte sie verwenden werden. Plug-in-Architekturen sind ein weiterer Bereich, in dem Reflection nützlich ist. Die Möglichkeit, Code dynamisch zu laden und festzustellen, ob es Typen gibt, die die richtige Schnittstelle für die Verwendung als Plugin implementieren, ist in diesen Situationen wichtig.

39voto

Nikhil Shekhar Punkte 546

Reflection ermöglicht die Instanziierung neuer Objekte, den Aufruf von Methoden und Get-/Set-Operationen auf Klassenvariablen dynamisch zur Laufzeit ohne vorherige Kenntnis der Implementierung.

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

Im obigen Beispiel ist der Null-Parameter das Objekt, für das Sie die Methode aufrufen möchten. Wenn die Methode statisch ist, liefern Sie null. Wenn die Methode nicht statisch ist, müssen Sie beim Aufrufen eine gültige MyObject-Instanz anstelle von null angeben.

Reflection ermöglicht Ihnen auch den Zugriff auf private Mitglieder/Methoden einer Klasse:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

.

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • Für die Inspektion von Klassen (auch Introspektion genannt) brauchen Sie das Reflection-Paket nicht zu importieren ( java.lang.reflect ). Auf die Klassen-Metadaten kann zugegriffen werden über java.lang.Class .

Reflection ist eine sehr leistungsfähige API, die aber bei übermäßigem Gebrauch die Anwendung verlangsamen kann, da sie alle Typen zur Laufzeit auflöst.

26voto

VeKe Punkte 8993

Java Reflection ist sehr leistungsfähig und kann sehr nützlich sein. Java Reflection macht es möglich um Klassen, Schnittstellen, Felder und Methoden zur Laufzeit zu inspizieren, ohne die Namen der Klassen, Methoden usw. zur Kompilierzeit zu kennen. Es ist auch möglich neue Objekte zu instanziieren, Methoden aufzurufen und Feldwerte mit Hilfe von Reflexion zu erhalten/zu setzen.

Ein kurzes Java-Reflection-Beispiel, um Ihnen zu zeigen, wie die Verwendung von Reflection aussieht:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

In diesem Beispiel wird das Class-Objekt aus der Klasse MyObject abgerufen. Mit Hilfe des Klassenobjekts erhält das Beispiel eine Liste der Methoden in dieser Klasse, iteriert die Methoden und gibt ihre Namen aus.

Wie das alles genau funktioniert, wird hier erklärt

Edit : Nach fast 1 Jahr bearbeite ich diese Antwort, da ich beim Lesen über Reflexion einige weitere Verwendungen von Reflexion gefunden habe.

  • Spring verwendet Bean-Konfigurationen wie z.B.:

    <bean id="someID" class="com.example.Foo"> <property name="someField" value="someValue" /> </bean>

Wenn der Spring-Kontext dieses < bean >-Element verarbeitet, wird er Class.forName(String) mit dem Argument "com.example.Foo" verwenden, um diese Klasse zu instanziieren.

Dann wird wieder die Reflexion verwendet, um den entsprechenden Setter für das < property >-Element abzurufen und dessen Wert auf den angegebenen Wert zu setzen.

  • Junit verwendet Reflection insbesondere zum Testen von privaten/geschützten Methoden.

Für private Methoden,

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

Für private Felder,

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

25voto

Isuru Jayakantha Punkte 288

Ein einfaches Beispiel zum Nachdenken. In einem Schachspiel weiß man zur Laufzeit nicht, was der Benutzer bewegen wird. Reflexion kann verwendet werden, um Methoden aufzurufen, die zur Laufzeit bereits implementiert sind:

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}

25voto

human.js Punkte 1327

Exemple :

Nehmen wir als Beispiel eine entfernte Anwendung, die Ihrer Anwendung ein Objekt gibt, das Sie mit ihren API-Methoden erhalten. Auf der Grundlage dieses Objekts müssen Sie nun möglicherweise eine Art von Berechnung durchführen.

Der Anbieter garantiert, dass es 3 Arten von Objekten gibt, und wir müssen Berechnungen durchführen, die auf der Art des Objekts basieren.

So könnten wir in 3 Klassen implementieren, die jeweils eine andere Logik enthalten. Offensichtlich sind die Objektinformationen zur Laufzeit verfügbar, so dass Sie nicht statisch kodieren können, um Berechnungen durchzuführen, daher wird Reflexion verwendet, um das Objekt der Klasse zu instanziieren, die Sie benötigen, um die Berechnung auf der Grundlage des Objekts, das vom Anbieter erhalten wurde, durchzuführen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X