Articulo de referencia

Programación reflexiva

En informática , la programación reflexiva o reflexión es la capacidad de un proceso para examinar, introspectar y modificar su propia estructura y comportamiento. [ 1 ] Anteced...

En informática , la programación reflexiva o reflexión es la capacidad de un proceso para examinar, introspectar y modificar su propia estructura y comportamiento. [ 1 ]

Antecedentes históricos

Las primeras computadoras se programaban en sus lenguajes ensambladores nativos , que eran inherentemente reflexivos, ya que estas arquitecturas originales podían programarse definiendo las instrucciones como datos y utilizando código automodificable . A medida que la mayor parte de la programación se trasladó a lenguajes compilados de alto nivel como ALGOL , COBOL , Fortran , Pascal y C , esta capacidad reflexiva desapareció en gran medida hasta que aparecieron nuevos lenguajes de programación con reflexión integrada en sus sistemas de tipos.

La tesis doctoral de Brian Cantwell Smith de 1982 introdujo la noción de reflexión computacional en lenguajes de programación procedimentales y la noción del intérprete metacircular como un componente de 3- Lisp . [ 2 ] [ 3 ]

Usos

La reflexión ayuda a los programadores a crear bibliotecas de software genéricas para visualizar datos, procesar diferentes formatos de datos, serializar y deserializar datos para la comunicación, o agrupar y desagrupar datos para contenedores o ráfagas de comunicación. Los sistemas reflectivos pueden proporcionar un tipo de espejo , que se utiliza como un reflejo desacoplado de un objeto o identificador.

El uso eficaz de la reflexión casi siempre requiere un plan: un marco de diseño, una descripción de la codificación, una biblioteca de objetos, un mapa de una base de datos o de las relaciones entre entidades.

La reflexión hace que un lenguaje sea más adecuado para el código orientado a redes. Por ejemplo, ayuda a lenguajes como Java a funcionar bien en redes al habilitar bibliotecas para la serialización, la agrupación y la variación de formatos de datos. Los lenguajes sin reflexión, como C, requieren el uso de compiladores auxiliares para tareas como la Notación de Sintaxis Abstracta ( ASN.1 ) para generar código para serialización y agrupación.

La reflexión puede utilizarse para observar y modificar la ejecución de un programa en tiempo de ejecución . Un componente de programa orientado a la reflexión puede supervisar la ejecución de un bloque de código y modificarse a sí mismo según el objetivo deseado de dicho bloque. Esto se suele lograr asignando código de programa dinámicamente en tiempo de ejecución.

En lenguajes de programación orientados a objetos como Java , la reflexión permite inspeccionar clases , interfaces , campos y métodos en tiempo de ejecución sin necesidad de conocer sus nombres en tiempo de compilación . También permite la creación de instancias de nuevos objetos y la invocación de métodos.

La reflexión se utiliza a menudo como parte de las pruebas de software , por ejemplo, para la creación/instanciación en tiempo de ejecución de objetos simulados .

La reflexión es también una estrategia clave para la metaprogramación .

En algunos lenguajes de programación orientados a objetos, como C# y Java , se puede usar la reflexión para eludir las reglas de accesibilidad de miembros . En el caso de las propiedades de C#, esto se logra escribiendo directamente en el campo subyacente (generalmente invisible) de una propiedad no pública. También es posible encontrar métodos no públicos de clases y tipos e invocarlos manualmente. Esto funciona tanto para archivos internos del proyecto como para bibliotecas externas, como los ensamblados de .NET y los archivos de Java.

Implementación

Un lenguaje que admite la reflexión proporciona una serie de características disponibles en tiempo de ejecución que de otro modo serían difíciles de lograr en un lenguaje de bajo nivel. Algunas de estas características son las capacidades de:

  • Descubra y modifique construcciones de código fuente (como bloques de código, clases , métodos, protocolos, etc.) como objetos de primera clase en tiempo de ejecución . Se proporcionan metadatos de objetos legibles como un espejo .
  • Convierte una cadena que coincida con el nombre simbólico de una clase o función en una referencia o invocación de esa clase o función. [ 4 ]
  • Evaluar una cadena como si fuera una instrucción de código fuente en tiempo de ejecución. [ 5 ] [ 6 ]
  • Crear un nuevo intérprete para el código de bytes del lenguaje con el fin de dar un nuevo significado o propósito a una construcción de programación.

Estas características se pueden implementar de diferentes maneras. En MOO , la reflexión forma parte natural del lenguaje de programación cotidiano. Cuando se llaman verbos (métodos), se rellenan varias variables como verb(el nombre del verbo que se llama) y this(el objeto sobre el que se llama al verbo) para dar el contexto de la llamada. La seguridad se gestiona normalmente accediendo a la pila de llamadas mediante programación: dado que callers()es una lista de los métodos mediante los que finalmente se llamó al verbo actual, realizar pruebas en callers()[0](el comando invocado por el usuario original) permite que el verbo se proteja contra el uso no autorizado.

Los lenguajes compilados dependen de su sistema de ejecución para obtener información sobre el código fuente. Un ejecutable de Objective-C compilado , por ejemplo, registra los nombres de todos los métodos en un bloque del ejecutable, proporcionando una tabla que los relaciona con los métodos subyacentes (o selectores para estos métodos) compilados en el programa. En un lenguaje compilado que admite la creación de funciones en tiempo de ejecución, como Common Lisp , el entorno de ejecución debe incluir un compilador o un intérprete.

La reflexión puede implementarse en lenguajes que no la incorporan mediante el uso de un sistema de transformación de programas para definir cambios automatizados en el código fuente.

Consideraciones de seguridad

La reflexión puede permitir a un usuario crear rutas de flujo de control inesperadas a través de una aplicación, eludiendo potencialmente las medidas de seguridad. Esto puede ser explotado por atacantes. [ 7 ] Vulnerabilidades históricas en Java causadas por reflexión insegura permitieron que el código recuperado de máquinas remotas potencialmente no confiables escapara del mecanismo de seguridad de la zona de pruebas de Java . Un estudio a gran escala de 120 vulnerabilidades de Java en 2013 concluyó que la reflexión insegura es la vulnerabilidad más común en Java, aunque no la más explotada. [ 8 ]

Rendimiento en tiempo de ejecución

Los sistemas de reflexión en tiempo de ejecución introducen una sobrecarga de rendimiento considerable . Por ejemplo, en Java , debido a que las operaciones reflectivas se resuelven dinámicamente en tiempo de ejecución, muchas optimizaciones del compilador y de la JVM (como la inserción de métodos en línea , el enlace estático y la especialización just-in-time agresiva) no se pueden aplicar completamente. En consecuencia, las llamadas reflectivas suelen ser más lentas que sus contrapartes resueltas estáticamente. Estudios de microbenchmark y a nivel de aplicación en Java han demostrado que las operaciones reflectivas pueden generar una sobrecarga sustancial en tiempo de ejecución, especialmente para la invocación de métodos y la creación dinámica de objetos, con ralentizaciones que van desde alrededor del 20-40% en casos moderados hasta más de 300 veces en escenarios de despacho altamente reflectivos. [ 9 ] En aplicaciones secuenciales, la reflexión puede aumentar significativamente el tiempo de ejecución y el consumo de memoria cuando se utiliza en rutas de código críticas para el rendimiento. En aplicaciones multihilo , las implementaciones reflectivas generalmente conservan la escalabilidad , pero aún así exhiben tiempos de ejecución absolutos notablemente más altos (comúnmente entre 1,5 y 10 veces más lentos) que el código equivalente no reflectivo. [ 9 ]

En lenguajes como C++ y Rust , la reflexión se realiza en tiempo de compilación . Los sistemas de reflexión en tiempo de compilación son menos robustos que los sistemas de reflexión en tiempo de ejecución, como los de Java y C#, pero no generan sobrecarga en tiempo de ejecución debido a que se realizan durante la compilación. [ 10 ]

Ejemplos

Los siguientes fragmentos de código crean una instanciafoo de una claseFoo e invocan su métodoPrintHello . Para cada lenguaje de programación , se muestran secuencias de llamadas normales y basadas en reflexión.

Lisp común

El siguiente ejemplo está escrito en Common Lisp utilizando el Sistema de Objetos de Common Lisp :

( defclass foo () ()) ( defmethod print-hello (( f foo )) ( format T "Hola desde ~S~%" f ));; Normal, sin reflexión ( let (( foo ( make-instance 'foo ))) ( print-hello foo ));; Con reflexión para buscar la clase llamada "foo" y el método ;; llamado "print-hello" que se especializa en "foo". ( let* (( foo-class ( find-class ( read-from-string "foo" ))) ( print-hello-method ( find-method ( symbol-function ( read-from-string "print-hello" )) nil ( list foo-class )))) ( funcall ( sb-mop:method-generic-function print-hello-method ) ( make-instance foo-class )))

do

La reflexión no es posible en C , aunque se pueden emular partes de la reflexión.

#include <stdio.h> #include <stdlib.h> #include <string.h>typedef struct { // ... } Foo ;typedef void ( * Método )( void * );// El método: Foo::printHello void Foo_printHello ( void * _ ) { printf ( "Hola, mundo! \n " ); }// Tabla de métodos simulada typedef struct { const char * name ; Method fn ; } MethodEntry ;const MethodEntry FOO_METHODS [] = { { "printHello" , Foo_printHello }, { NULL , NULL } // Centinela para marcar el final };// Simular búsqueda de método reflectivo Método findMethodByName ( const char * name ) { for ( size_t i = 0 ; FOO_METHODS [ i ]. name ; i ++ ) { if ( strcmp ( FOO_METHODS [ i ]. name , name ) == 0 ) { return FOO_METHODS [ i ]. fn ; } } return NULL ; }int main () { // Sin reflexión Foo foo ; Foo_printHello ( & foo );// Con reflexión emulada Foo * reflectado = ( Foo * ) malloc ( sizeof ( Foo )); if ( ! reflectado ) { fprintf ( stderr , "Error en la asignación de memoria \n " ); return EXIT_FAILURE ; }const char * nombre = "printHello" ; Método m = findMethodByName ( nombre );if ( m ) { m ( reflected ); } else { fprintf ( stderr , "Método '%s' no encontrado \n " , name ); free ( reflected ); return EXIT_FAILURE ; }libre ( reflejado ); devolver EXIT_SUCCESS ; }

C++

El siguiente ejemplo está en C++ (usando reflexión añadida en C++26 ). [ 11 ]

importar std ;using std :: string_view ; using std :: views :: filter ; using std :: meta :: access_context ; using std :: meta :: exception ; using std :: meta :: info ;espacio de nombres meta = std :: meta ;consteval bool isNonstaticMethod ( info mem ) noexcept { return meta :: is_class_member ( mem ) && ! meta :: is_static_member ( mem ) && meta :: is_function ( mem ); }consteval info findMethod ( info type , string_view name ) { for ( info member : meta :: members_of ( type , access_context :: current ()) | filter ( isNonstaticMethod )) { if ( meta :: has_identifier ( member ) && meta :: identifier_of ( member ) == name ) { return member ; } } // Nota: esto es std::meta::exception, no std::exception throw exception ( std :: format ( "Error al recuperar el método {} del tipo {}" , name , meta :: identifier_of ( type )), ^^ findMethod ); }template < info T , const char * Name > constexpr auto createInvokerImpl = []() -> auto { static constexpr info M = findMethod ( T , Name ); contract_assert ( meta :: parameters_of ( M ). size () == 0 && meta :: return_type_of ( M ) == ^^ void ); return []([ : T : ] & instance ) -> void { instance .[ : M : ](); }; }();consteval info createInvoker ( info type , string_view name ) { return meta :: substitute ( ^^ createInvokerImpl , { meta :: reflect_constant ( type ), meta :: reflect_constant_string ( name ) } ); }clase Foo { privado : // ... público : Foo () = predeterminado ;void printHello () const { std :: println ( "Hola, mundo!" ); } };int main ( int argc , char * argv []) { Foo foo ;// Sin reflexión foo.printHello ( ) ;// Con reflexión auto invokePrint = [ : createInvoker ( ^^ Foo , "printHello" ) : ]; invokePrint ( foo );devolver 0 ; }

DO#

El siguiente ejemplo está escrito en C# :

espacio de nombres Wikipedia.Ejemplos ;usando System ; usando System.Reflection ;clase Foo { // ...public void PrintHello () { Console . WriteLine ( "Hola, mundo!" ); } }public class InvokeFooExample { static void Main ( string [] args ) { // Sin reflexión Foo foo = new (); foo . PrintHello ();// Con reflexión Object reflectiveFoo = Activator . CreateInstance ( typeof ( Foo )); MethodInfo method = reflectiveFoo . GetType () . GetMethod ( "PrintHello" ); method . Invoke ( foo , null ); } }

Delphi, Object Pascal

Este ejemplo de Delphi y Object Pascal asume que se ha declarado una clase TFoo en una unidad llamada Unit1 :

utiliza RTTI , Unidad1 ;procedimiento SinReflexión ; var Foo : TFoo ; inicio Foo : = TFoo.Crear ; intentar Foo.Hola ; finalmente Foo.Liberar ; fin ; fin ;procedimiento WithReflection ; var RttiContext : TRttiContext ; RttiType : TRttiInstanceType ; Foo : TObject ; begin RttiType := RttiContext.FindType ( ' Unit1.TFoo ' ) as TRttiInstanceType ; Foo : = RttiType.GetMethod ( 'Create ' ) . Invoke ( RttiType.MetaclassType , [ ] ) . AsObject ; try RttiType.GetMethod ( ' Hello ' ) . Invoke ( Foo , [ ] ) ; finally Foo.Free ; end ; end ;

CE

El siguiente ejemplo está en eC:

// Sin reflexión Foo foo {}; foo . hola ();// Con reflexión Clase fooClass = eSystem_FindClass ( __thisModule , "Foo" ); Instancia foo = eInstance_New ( fooClass ); Método m = eClass_FindMethod ( fooClass , "hello" , fooClass . module ); (( void ( * )())( void * ) m . function )( foo );

Ir

El siguiente ejemplo está escrito en Go :

import ( "fmt" "reflect" )tipo Foo struct {}func ( f Foo ) Hello () { fmt . Println ( "Hola, mundo!" ) }func main () { // Sin reflexión var f Foo f . Hello ()// Con reflexión var fT reflect . Type = reflect . TypeOf ( Foo {}) var fV reflect . Value = reflect . New ( fT )var m reflect . Value = fV . MethodByName ( "Hello" )if m . IsValid () { m . Call ( nil ) } else { fmt . Println ( "Método no encontrado" ) } }

Java

El siguiente ejemplo está en Java :

paquete org.wikipedia.examples ;import java.lang.reflect.Method ;clase Foo { // ...public void printHello () { System . out . println ( "Hola, mundo!" ); } }public class InvokeFooExample { public static void main ( String [] args ) { // Sin reflexión Foo foo = new Foo (); foo . printHello ();// Con reflexión try { Foo reflectiveFoo = Foo . class . getDeclaredConstructor () . newInstance ();Método m = reflectiveFoo . getClass () . getDeclaredMethod ( "printHello" , new Class <?>[ 0 ] ); m . invoke ( reflectiveFoo ); } catch ( ReflectiveOperationException e ) { System . err . printf ( "Ocurrió un error: %s%n" , e . getMessage ()); } } }

Java también proporciona una clase interna (no oficialmente en la Biblioteca de Clases de Java ) en el módulojdk.unsupported , sun.reflect.Reflectionque es utilizada por sun.misc.Unsafe. Contiene un método, para obtener la clase haciendo una llamada a una profundidad especificada. [ 12 ] Esto ahora ha sido reemplazado por el uso de la clase y su método .staticClass<?>getCallerClass(intdepth)java.lang.StackWalker.StackFrameClass<?>getDeclaringClass()

JavaScript, TypeScript

El siguiente ejemplo está escrito en JavaScript y TypeScript :

importar 'reflect-metadata' ;// Sin reflexión const foo = new Foo (); foo . hello ();// Con reflexión const foo = Reflect.construct ( Foo ) ; const hello = Reflect.get ( foo , ' hello' ) ; Reflect.apply ( hello , foo , [ ] );// Con eval eval ( 'new Foo().hello()' );

El siguiente es el mismo ejemplo en TypeScript :

importar 'reflect-metadata' ;// Sin reflexión const foo : Foo = new Foo (); foo . hello ();// Con reflexión const foo : Foo = Reflect . construct ( Foo ); const hello : ( this : Foo ) => void = Reflect . get ( foo , 'hello' ) as ( this : Foo ) => void ; Reflect . apply ( hello , foo , []);// Con eval eval ( 'new Foo().hello()' );

Julia

El siguiente ejemplo está escrito en Julia :

julia> struct Point x :: Int y end# Inspección con reflexión julia> fieldnames ( Punto ) (:x, :y)julia> tipos de campo ( Punto ) (Int64, Cualquiera)julia> p = Punto ( 3 , 4 )# Acceso mediante reflexión julia> getfield ( p , :x ) 3

Kotlin

Utilizando la reflexión de Java:

paquete org.wikipedia.examplesimport java.lang.reflect.Methodclase Foo { // ... constructor ()fun printHello () { println ( "Hola, mundo!" ) } }fun main ( args : Array < String > ) { // Sin reflexión val foo = Foo () foo . printHello ()// Con reflexión try { // Foo::class.java recupera un java.lang.Class<Foo> val reflectiveFoo = Foo :: class . java . getDeclaredConstructor () . newInstance ()val m : Method = reflectiveFoo . javaClass . getDeclaredMethod ( "printHello" )m.invoke ( reflectedFoo ) } catch ( e : ReflectiveOperationException ) { System.err.printf ( " Ocurrió un error : % s % n " , e.message ) } }

Usando Kotlin puro:

paquete org.wikipedia.examplesimport kotlin.reflect.full.createInstance import kotlin.reflect.full.functionsclase Foo { // ... fun printHello () { println ( "Hola, mundo!" ) } }fun main ( args : Array < String > ) { // Sin reflexión val foo = Foo () foo . printHello ()// Con reflexión try { val kClass = Foo :: class val reflectiveFoo = kClass . createInstance () val function = kClass . functions . first { it . name == "printHello" } function . call ( reflectiveFoo ) } catch ( e : Exception ) { System . err . printf ( "Ocurrió un error: %s%n" , e . message ) } }

Objetivo-C

El ejemplo que se muestra a continuación está escrito en Objective-C , lo que implica que se utiliza el framework OpenStep o Foundation Kit :

// Clase Foo. @interface Foo : NSObject - ( void ) hola ; @end// Enviando "hola" a una instancia de Foo sin reflexión. Foo * obj = [[ Foo alloc ] init ]; [ obj hello ];// Enviando "hola" a una instancia de Foo con reflexión. id obj = [[ NSClassFromString ( @"Foo" ) alloc ] init ]; [ obj performSelector : @selector ( hola )];

Perl

El siguiente ejemplo está escrito en Perl :

# Sin reflexión my $foo = Foo -> new ; $foo -> hello ;# o Foo -> nuevo -> hola ;# Con reflexión mi $class = "Foo" mi $constructor = "new" ; mi $method = "hello" ;mi $f = $class -> $constructor ; $f -> $method ;# o $class -> $constructor -> $method ;# con eval eval "new Foo->hello;" ;

PHP

El siguiente ejemplo está en PHP : [ 13 ]

// Sin reflexión $foo = new Foo (); $foo -> hello ();// Con reflexión, usando la API Reflections $reflector = new ReflectionClass ( "Foo" ); $foo = $reflector -> newInstance (); $hello = $reflector -> getMethod ( "hello" ); $hello -> invoke ( $foo );

Pitón

El siguiente ejemplo está escrito en Python :

from typing import Anyclase Foo : # ... def print_hello ( self ) -> None : print ( "Hola, mundo!" )if __name__ == "__main__" : # Sin reflexión obj : Foo = Foo () obj.print_hello ( )# Con reflexión obj : Foo = globals ()[ "Foo" ]() _ : Any = getattr ( obj , "print_hello" )()# Con eval eval ( "Foo().print_hello()" )

R

El siguiente ejemplo está en R :

# Sin reflexión, suponiendo que foo() devuelve un objeto de tipo S3 que tiene el método "hello" obj <- foo () hello ( obj )# Con reflexión class_name <- "foo" generic_having_foo_method <- "hello" obj <- do.call ( class_name , list ()) do.call ( generic_having_foo_method , alist ( obj ))

Rubí

El siguiente ejemplo está escrito en Ruby :

# Sin reflexión obj = Foo . nuevo obj . hola# Con reflexión obj = Object . const_get ( "Foo" ) . new obj . send :hello# Con eval eval "Foo.new.hello"

Óxido

El ejemplo que se muestra a continuación está escrito en Rust (utilizando macros procedimentales ).

// Una macro básica que registra una cadena de nombre de método en una llamada a método real macro_rules! invoke_method { ( $instance : expr , $method_name : expr ) => { match $method_name { "print_hello" => $instance . print_hello (), _ => eprintln! ( "Ocurrió un error: Método no encontrado." ), } }; }struct Foo ;impl Foo { fn print_hello ( & self ) { println! ( "Hola, mundo!" ); } }fn main () { let foo = Foo ;// Secuencia de llamada normal foo . print_hello ();// Secuencia de estilo reflexión mediante mapeo en tiempo de compilación let method_to_call = "print_hello" ; invoke_method ! ( foo , method_to_call ); }

Rápido

La reflexión en Swift es de solo lectura, por lo que la invocación dinámica solo es posible a través de Objective-C .

Fundación de importaciónclase Foo : NSObject { @objc func printHello () { print ( "Hola, mundo!" ) } }clase InvokeFooExample { static func main () { // Sin reflexión let foo = Foo () foo . printHello ()// Con "reflexión" (tiempo de ejecución de Objective-C) let reflectiveFoo = Foo ()let selector = #selector ( Foo . printHello )if reflectiveFoo . responds ( to : selector ) { reflectiveFoo . perform ( selector ) } } }

El sistema de reflexión de Swift, con Swift.Mirror, tiene un alcance mucho más limitado:

Fundación de importaciónclase Foo { func printHello () { print ( "Hola, mundo!" ) } }sea ​​foo = Foo ()sea ​​espejo = Espejo ( reflejando : foo )print ( type ( of : foo ) ) // Foo print ( mirror.children.count ) // Solo propiedades

Xojo

El siguiente es un ejemplo usando Xojo :

' Sin reflexión Dim fooInstance As New Foo fooInstance . PrintHello' Con reflexión Dim classInfo As Introspection . Typeinfo = GetTypeInfo ( Foo ) Dim constructors () As Introspection . ConstructorInfo = classInfo . GetConstructors Dim fooInstance As Foo = constructors ( 0 ). Invoke Dim methods () As Introspection . MethodInfo = classInfo . GetMethods For Each m As Introspection . MethodInfo In methods If m . Name = "PrintHello" Then m . Invoke ( fooInstance ) End If Next

Véase también

Referencias

Citas

  1. Tutorial sobre reflexión conductual y su implementación por Jacques Malenfant et al. (PDF) , desconocido, archivado del original (PDF) el 21 de agosto de 2017 , recuperado el 23 de junio de 2019
  2. Brian Cantwell Smith, Reflexión procedimental en lenguajes de programación , Departamento de Ingeniería Eléctrica y Ciencias de la Computación, Instituto Tecnológico de Massachusetts, tesis doctoral, 1982.
  3. Brian C. Smith. Reflexión y semántica en un lenguaje procedimental. Archivado el 13 de diciembre de 2015 en Wayback Machine . Informe técnico MIT-LCS-TR-272, Instituto Tecnológico de Massachusetts, Cambridge, Massachusetts, enero de 1982.
  4. "CLHS: Función INTERN" . www.ai.mit.edu . Consultado el 27 de marzo de 2026 .
  5. "Funciones integradas" . Documentación de Python . Consultado el 27 de marzo de 2026 .
  6. "eval() - JavaScript | MDN" . MDN Web Docs . 2026-01-21 . Consultado el 2026-03-27 .
  7. Barros, Paulo; Just, René; Millstein, Suzanne; Vines, Paul; Dietl, Werner; d'Amorim, Marcelo; Ernst, Michael D. (agosto de 2015). Análisis estático del flujo de control implícito: resolución de la reflexión de Java y las intenciones de Android (PDF) (Informe). Universidad de Washington. UW-CSE-15-08-01 . Recuperado el 7 de octubre de 2021 .
  8. Eauvidoum, Ieu; disk noise (5 de octubre de 2021). "Veinte años escapando del entorno aislado de Java" . Phrack . Vol. 10, n.º 46. Consultado el 7 de octubre de 2021 .  
  9. 1 2 Miguel García, Francisco Ortín. Caracterización del uso y el impacto en el rendimiento de la reflexión en Java: un estudio empírico , ACM Transactions on Software Engineering and Methodology, 2026.
  10. Tristan Soliven (1 de mayo de 2026). "Reflexión en C++26: qué cambia realmente para grandes bases de código" . wholetomato.com . Whole Tomato.
  11. cppreference.com. "Encabezado de biblioteca estándar <meta /> (C++26)" . cppreference.com . cppreference.com . Consultado el 17 de mayo de 2026 .
  12. "Reflexión (Plataforma Java SE 9)" . cr.openjdk.org . OpenJDK . Consultado el 10 de octubre de 2025 .
  13. "PHP: ReflectionClass - Manual" . www.php.net .

Fuentes

  • Jonathan M. Sobel y Daniel P. Friedman. Una introducción a la programación orientada a la reflexión (1996), Universidad de Indiana .
  • Técnica antirreflejo que utiliza C# y un envoltorio C++/CLI para prevenir el robo de código.

Lecturas adicionales

  • Ira R. Forman y Nate Forman, Java Reflection in Action (2005), ISBN 1-932394-18-4
  • Ira R. Forman y Scott Danforth, Poniendo las metaclases en práctica (1999), ISBN 0-201-43305-2
  • Reflexión en la programación lógica, funcional y orientada a objetos: un breve estudio comparativo.
  • Introducción a la programación orientada a la reflexión
  • Páginas de Brian Foote sobre la reflexión en la charla informal.
  • Tutorial de la API de reflexión de Java de Oracle