Reflection (programming)
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 person
and 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 Object
provides 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 rufe
that 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 getVorname
the object person
and output its return value.
puts "Der Vorname lautet [person rufe getVorname] ";