Reflexion (Programmierung) - LinkFang.de





Reflexion (Programmierung)


In der Programmierung bedeutet Reflexion (englisch reflection) oder Introspektion, dass ein Programm seine eigene Struktur kennt und diese modifizieren kann.

Auf unterster Ebene kann Maschinencode im RAM, der von einem Mikroprozessor ausgeführt wird, als reflexiv bezeichnet werden. Ein solches Programm ist in der Lage, seine Anweisungen wie Daten zu behandeln und kann deshalb seine Struktur analysieren und verändern. Reflexion wird häufig von Frameworks oder Sprachen unterstützt, die in einer virtuellen Maschine ausgeführt werden, beispielsweise .NET, Java oder Smalltalk und viele interpretierende Sprachen.

Eine wichtige Rolle spielt Reflexion im Zusammenhang mit typensicherer Programmierung, aber auch in Fragen der Persistenz (persistente Datenhaltung von Objekten und deren Beziehungen).

Reflexion ermöglicht es bei objektorientierter Programmierung beispielsweise, zur Laufzeit Informationen über Klassen oder deren Instanzen abzufragen, beispielsweise in Objective-C (dort typischerweise Introspektion genannt). Bei einer Methode sind das unter anderem deren Sichtbarkeit, der Datentyp des Rückgabewertes oder der Typ der Übergabeparameter. Die Umsetzung der Abfragemöglichkeiten ist sprachspezifisch.

Für die Realisierung der Reflexion ist das Speichern von Metainformation im Binärcode des Programms notwendig. Bei interpretierenden Programmiersprachen liegt zur Ausführungszeit der ursprüngliche Programmcode vor, was neben dem Zugriff auf die Strukturinformation (Methodendeklaration) auch den Zugriff auf die Implementierung ermöglicht. Beispiele dafür sind PHP, Lisp, Python, Smalltalk und Tcl.

Aber auch Java und alle Sprachen für Verwendung mit dem .NET-Framework, wie z. B. C#, Object Pascal, VB.NET oder IronPython unterstützen die Reflexion, die das .NET Framework von sich aus zur Verfügung stellt. Alle Sprachen, die das .NET-Framework verwenden, müssen laut CLS (Common Language Specification) die entsprechenden Informationen als Metadaten speichern.

Die Ausführungsgeschwindigkeit von Code per Reflexion ist für gewöhnlich langsamer als die von statischem Code. Dies liegt unter anderem an den Stringvergleichen der entsprechenden Namen der gewünschten Methoden, Eigenschaften usw. mit den Einträgen in den Metadaten. Jedoch bietet Reflexion eine sehr hohe Laufzeitflexibilität, da Code dynamisch aufgerufen werden kann, neue Instanzen erstellt oder sogar Typen und Objekte dynamisch neu strukturiert werden können.

Beispiele

C#

Das folgende Beispiel zeigt eine Methode, die eine beliebige andere Methode eines gegebenen Objekts aufruft und deren Rückgabewert zurückgibt. Aus Gründen der Vereinfachung unterstützt dieses Beispiel nur den Aufruf von Methoden ohne Parameter, die Zeichenketten ("String") zurückgeben.

  public String GetStringProperty(Object obj, String methodName)
  {
    String value = null;
    try  {
         MethodInfo methodInfo = obj.GetType().GetMethod(methodName);
         value = (String)methodInfo.Invoke(obj, new Object[0]);
    } catch (Exception e) {}
    //Fehlerbehandlung zwecks Übersichtlichkeit nicht implementiert.
 
    return value;
  }

Common Lisp

(funcall (find-symbol "SIN") 3)

Java

Das folgende Beispiel zeigt eine Methode, die der Funktionalität des C#-Beispiels entspricht.

public String getStringProperty(Object object, String methodname) {
    String value = null;
    try {
        Method getter = object.getClass().getMethod(methodname, new Class[0]);
        value = (String) getter.invoke(object, new Object[0]);
    } catch (Exception e) {}
    //Fehlerbehandlung zwecks Übersichtlichkeit nicht implementiert.
 
    return value;
}

Die folgende Anweisung würde dann die Methode getVorname() des Objekts person aufrufen und deren Rückgabewert ausgeben.

System.out.println("Vorname von " + person + " ist "
                   + getStringProperty(person, "getVorname"));

PHP

<?php
$reflectionExampleObj = new ReflectionClass('ExampleClass');
Reflection::export($reflectionExampleObj );
?>

Die angegebene Anweisung würde dann die Eigenschaften der Klasse "ExampleClass" als Ausgabe zurückliefern.

Die folgende Anweisung liefert beispielsweise die statischen Variablen der Klasse, wenn welche existieren:

<?php
$reflectionExampleObj = new ReflectionClass('ExampleClass');
$reflectionExampleObj->getStaticVariables();
?>

Python

>>> # die Klasse
>>> class Person(object):
...    def __init__(self, name):
...        self.name = name
...    def say_hello(self):
...        return 'Hallo %s!' % self.name
...
>>> # das Objekt
>>> ute = Person('Ute')
>>> # direkt
>>> print ute.say_hello()
Hallo Ute!
>>> # Reflexion
>>> m = getattr(ute, 'say_hello')
>>> # (entspricht ute.say_hello())
>>> print m()
Hallo Ute!

Ruby

"a String".class # ergibt "String"
"a String".respond_to?(:size) # ergibt true -> Objekt kann Methode size ausführen
"a String".methods # ergibt einen Array mit allen Methoden des Objektes
"a String".method(:concat).arity # gibt die Anzahl der Parameter an,
                                  # die die Methode concat verlangt
class Book
  def initialize(*parameters)
    @title, @author, @chapters = parameters
  end
end
a_book = Book.new("Book Title", "Someone", ["chapter I", "chapter II", "chapter III"])
a_book.instance_variables # ergibt einen Array aller Objektinstanzvariablen:
                          # ["@title", "@author", "@chapters"]
Book.instance_methods # gibt alle Instanzmethoden der Klasse Book aus.

Smalltalk

Statt Methodenaufrufen auf Objekten werden diesen in Smalltalk Nachrichten gesendet. Die Oberklasse Object stellt die Nachricht perform: (sowie Varianten für Aufrufe mit Parametern) zur Verfügung, mit welcher einem Objekt die zu dem übergebenen Symbol entsprechende Nachricht gesendet wird. Die folgenden Codebeispiele (für GNU Smalltalk ) sind somit äquivalent:

s := Set new.
s add: 4.
s printNl.
s := Set perform: #new.
s perform: #add: with: 4.
s perform: #printNl.

Tcl

Das folgende Beispiel zeigt eine Methode rufe, die der Funktionalität des obigen C#- und Java-Beispiels entspricht.

oo::class create Person {
 
  variable name vorname
 
  constructor {n v} {
    set name $n
    set vorname $v
  }

  # Diese gewöhnliche, parameterlose Methode liefert den Vornamen
  method getVorname {} {
    return $vorname
  } 

  # Diese Methode ruft die Methode auf, deren Name als Parameter mitgegeben wird.
  method rufe {methode} {
    return [[self] $methode]
  }
}

# Erzeugen eines Objekts person der Klasse Person
Person create person Meier Franz

Die folgende Anweisung würde dann die Methode getVorname des Objekts person aufrufen und deren Rückgabewert ausgeben.

puts "Der Vorname lautet [person rufe getVorname] ";

Weblinks


Kategorien: Programmierung

Quelle: Wikipedia - http://de.wikipedia.org/wiki/Reflexion (Programmierung) (Vollständige Liste der Autoren des Textes [Versionsgeschichte])    Lizenz: CC-by-sa-3.0

Änderungen: Alle Bilder mit den meisten Bildunterschriften wurden entfernt. Ebenso alle zu nicht-existierenden Artikeln/Kategorien gehenden internen Wikipedia-Links (Bsp. Portal-Links, Redlinks, Bearbeiten-Links). Entfernung von Navigationsframes, Geo & Normdaten, Mediadateien, gesprochene Versionen, z.T. ID&Class-Namen, Style von Div-Containern, Metadaten, Vorlagen, wie lesenwerte Artikel. Ansonsten sind keine Inhaltsänderungen vorgenommen worden. Weiterhin kann es durch die maschinelle Bearbeitung des Inhalts zu Fehlern gerade in der Darstellung kommen. Darum würden wir jeden Besucher unserer Seite darum bitten uns diese Fehler über den Support mittels einer Nachricht mit Link zu melden. Vielen Dank!

Stand der Informationen: August 201& - Wichtiger Hinweis: Da die Inhalte maschinell von Wikipedia übernommen wurden, ist eine manuelle Überprüfung nicht möglich. Somit garantiert LinkFang.de nicht die Richtigkeit und Aktualität der übernommenen Inhalte. Sollten die Informationen mittlerweile fehlerhaft sein, bitten wir Sie darum uns per Support oder E-Mail zu kontaktieren. Wir werden uns dann innerhalb von spätestens 10 Tagen um Ihr Anliegen kümmern. Auch ohne Anliegen erfolgt mindestens alle drei Monate ein Update der gesamten Inhalte.