Reflection (programming)

from Wikipedia, the free encyclopedia

Reflection ( English reflection ) or introspection is in the programming that a program to know its own structure and may modify this possibly.

Details

At the lowest level, machine code in RAM that is executed by a microprocessor can be described as reflexive. Such a program is able to treat its instructions like data and can therefore analyze and change its structure. Reflection is often supported by frameworks or languages ​​that run in a virtual machine, such as Java , .NET or Smalltalk, and many interpreting languages.

Reflection plays an important role in connection with type-safe programming, but also in questions of persistence (persistent data management of objects and their relationships ).

In object-oriented programming , reflection makes it possible , for example, to query information about classes or their instances at runtime , for example in Objective-C (typically called introspection there). In the case of a method , this includes its visibility , the data type of the return value or the type of transfer parameters . The implementation of the query options is language-specific.

To implement the reflection, it is necessary to save meta information in the binary code of the program. In interpreting programming languages , the original program code is available at execution time, which in addition to access to the structure information (method declaration) also enables access to the implementation. Examples are PHP , Lisp , Python , Smalltalk and Tcl .

But also Java and all languages ​​for use with the .NET Framework , such as B. C # , Object Pascal , VB.NET or IronPython support the reflection that the .NET Framework provides by itself. All languages ​​that use the .NET Framework must, according to the CLS (Common Language Specification), save the relevant information as metadata.

Code execution through reflection is usually slower than static code. This is due, among other things, to the string comparisons of the corresponding names of the desired methods, properties, etc. with the entries in the metadata. However, reflection offers a very high level of runtime flexibility, as code can be called dynamically, new instances can be created or even types and objects can be dynamically restructured.

Examples

C #

The following example shows a method that calls any other method on a given object and returns its return value. For the sake of simplicity, this example only supports calling methods without parameters that return character strings ("String").

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

    return val;
  }

Common Lisp

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

Java

The following example shows a method that corresponds to the functionality of the C # example.

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;
}

The following statement would then call the method of getVorname()the object personand output its return value.

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

PHP

$reflectionExampleObj = new ReflectionClass('ExampleClass');
Reflection::export($reflectionExampleObj);

The specified instruction would then return the properties of the "ExampleClass" class as output.

For example, the following statement returns the static variables of the class, if any exist:

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

python

class Person(object):
    def __init__(self, name):
        self.name = name
    
    def say_hello(self):
        return 'Hallo %s!' % self.name

ute = Person('Ute')

# direkt
print(ute.say_hello()) # Hallo Ute!

# Reflexion entspricht ute.say_hello()
m = getattr(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.

Small talk

Instead of method calls on objects, these are sent in Smalltalk messages. The superclass Objectprovides the message perform:(as well as variants for calls with parameters) with which the message corresponding to the transferred symbol is sent to an object. The following code examples (for GNU Smalltalk) are therefore equivalent:

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

Tcl

The following example shows a method rufethat corresponds to the functionality of the C # and Java example above.

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

The following statement would then call the method of getVornamethe object personand output its return value.

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

Web links

Wiktionary: Reflection  - explanations of meanings, word origins, synonyms, translations