Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Reflective programming

From Wikipedia, the free encyclopedia
Ability of a process to examine and modify itself
Not to be confused withReflection (computer graphics).

Incomputer science,reflective programming orreflection is the ability of aprocess to examine,introspect, and modify its own structure and behavior.[1]

Historical background

[edit]

The earliest computers were programmed in their nativeassembly languages, which were inherently reflective, as these original architectures could be programmed by defining instructions as data and usingself-modifying code. As the bulk of programming moved to higher-levelcompiled languages such asALGOL,COBOL,Fortran,Pascal, andC, this reflective ability largely disappeared until new programming languages with reflection built into their type systems appeared.[citation needed]

Brian Cantwell Smith's 1982 doctoral dissertation introduced the notion of computational reflection in proceduralprogramming languages and the notion of themeta-circular interpreter as a component of 3-Lisp.[2][3]

Uses

[edit]

Reflection helps programmers make generic software libraries to display data, process different formats of data, performserialization and deserialization of data for communication, or do bundling and unbundling of data for containers or bursts of communication.

Effective use of reflection almost always requires a plan: A design framework, encoding description, object library, a map of a database or entity relations.

Reflection makes a language more suited to network-oriented code. For example, it assists languages such asJava to operate well in networks by enabling libraries for serialization, bundling and varying data formats. Languages without reflection such asC are required to use auxiliary compilers for tasks likeAbstract Syntax Notation to produce code for serialization and bundling.

Reflection can be used for observing and modifying program execution atruntime. A reflection-oriented program component can monitor the execution of an enclosure of code and can modify itself according to a desired goal of that enclosure. This is typically accomplished by dynamically assigning program code at runtime.

Inobject-oriented programming languages such asJava, reflection allowsinspection of classes, interfaces, fields and methods at runtime without knowing the names of the interfaces, fields, methods atcompile time. It also allowsinstantiation of new objects andinvocation of methods.

Reflection is often used as part ofsoftware testing, such as for the runtime creation/instantiation ofmock objects.

Reflection is also a key strategy formetaprogramming.

In some object-oriented programming languages such asC# andJava, reflection can be used to bypassmember accessibility rules. For C#-properties this can be achieved by writing directly onto the (usually invisible) backing field of a non-public property. It is also possible to find non-public methods of classes and types and manually invoke them. This works for project-internal files as well as external libraries such as.NET's assemblies and Java's archives.

Implementation

[edit]
icon
This sectiondoes notcite anysources. Please helpimprove this section byadding citations to reliable sources. Unsourced material may be challenged andremoved.(January 2008) (Learn how and when to remove this message)

A language that supports reflection provides a number of features available at runtime that would otherwise be difficult to accomplish in a lower-level language. Some of these features are the abilities to:

  • Discover and modifysource-code constructions (such as code blocks,classes, methods, protocols, etc.) asfirst-class objects atruntime.
  • Convert astring matching the symbolic name of a class or function into a reference to or invocation of that class or function.
  • Evaluate a string as if it were a source-code statement at runtime.
  • Create a newinterpreter for the language'sbytecode to give a new meaning or purpose for a programming construct.

These features can be implemented in different ways. InMOO, reflection forms a natural part of everyday programming idiom. When verbs (methods) are called, various variables such asverb (the name of the verb being called) andthis (the object on which the verb is called) are populated to give the context of the call. Security is typically managed by accessing the caller stack programmatically: Sincecallers() is a list of the methods by which the current verb was eventually called, performing tests oncallers()[0] (the command invoked by the original user) allows the verb to protect itself against unauthorised use.

Compiled languages rely on their runtime system to provide information about the source code. A compiledObjective-C executable, for example, records the names of all methods in a block of the executable, providing a table to correspond these with the underlying methods (or selectors for these methods) compiled into the program. In a compiled language that supports runtime creation of functions, such asCommon Lisp, the runtime environment must include a compiler or an interpreter.

Reflection can be implemented for languages without built-in reflection by using aprogram transformation system to define automated source-code changes.

Security considerations

[edit]

Reflection may allow a user to create unexpectedcontrol flow paths through an application, potentially bypassing security measures. This may be exploited by attackers.[4] Historicalvulnerabilities in Java caused by unsafe reflection allowed code retrieved from potentially untrusted remote machines to break out of the Javasandbox security mechanism. A large scale study of 120 Java vulnerabilities in 2013 concluded that unsafe reflection is the most common vulnerability in Java, though not the most exploited.[5]

Examples

[edit]

The following code snippets create aninstancefoo ofclassFoo and invoke itsmethodPrintHello. For eachprogramming language, normal and reflection-based call sequences are shown.

Common Lisp

[edit]

The following is an example inCommon Lisp using theCommon Lisp Object System:

(defclassfoo()())(defmethodprint-hello((ffoo))(formatT"Hello from ~S~%"f));; Normal, without reflection(let((foo(make-instance'foo)))(print-hellofoo));; With reflection to look up the class named "foo" and the method;; named "print-hello" that specializes on "foo".(let*((foo-class(find-class(read-from-string"foo")))(print-hello-method(find-method(symbol-function(read-from-string"print-hello"))nil(listfoo-class))))(funcall(sb-mop:method-generic-functionprint-hello-method)(make-instancefoo-class)))

C

[edit]

Reflection is not possible inC, though parts of reflection can be emulated.

#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstruct{// ...}Foo;typedefvoid(*Method)(void*);// The method: Foo::printHellovoidFoo_printHello([[maybe_unused]]void*this){(void)this;// Instance ignored for a static methodprintf("Hello, world!\n");}// Simulated method tabletypedefstruct{constchar*name;Methodfn;}MethodEntry;MethodEntryfooMethods[]={{"printHello",Foo_printHello},{NULL,NULL}// Sentinel to mark end};// Simulate reflective method lookup[[nodiscard]]MethodfindMethodByName(constchar*name){for(size_ti=0;fooMethods[i].name;i++){if(strcmp(fooMethods[i].name,name)==0){returnfooMethods[i].fn;}}returnNULL;}intmain(){// Without reflectionFoofooInstance;Foo_printHello(&fooInstance);// With emulated reflectionFoo*fooReflected=malloc(sizeof(Foo));if(!fooReflected){fprintf(stderr,"Memory allocation failed\n");return1;}constchar*methodName="printHello";Methodm=findMethodByName(methodName);if(m){m(fooReflected);}else{fprintf(stderr,"Method '%s' not found\n",methodName);}free(fooReflected);return0;}

C++

[edit]

The following is an example inC++ (using reflection added inC++26).

importstd;usingStringView=std::string_view;template<typenameT>usingVector=std::vector<T>;usingAccessContext=std::meta::access_context;usingReflectionException=std::meta::exception;usingInfo=std::meta::info;inlineconstexprdecltype(std::views::filter)Filter=std::views::filter;[[nodiscard]]constevalboolisNonstaticMethod(Infomem)noexcept{returnstd::meta::is_class_member(mem)&&!std::meta::is_static_member(mem)&&std::meta::is_function(mem);}[[nodiscard]]constevalinfofindMethod(Infotype,StringViewname){constexprautoctx=AccessContext::current();Vector<Info>members=std::meta::members_of(type,ctx);for(Infomember:members|Filter(isNonstaticMethod)){if(std::meta::name_of(member)==name){returnmember;}}throwReflectionException(std::format("Failed to retrieve method {} from type {}",name,std::meta::name_of(type)),^^findMethod);}template<InfoType,StringViewName>constexprautocreateInvokerImpl=[]()->auto{usingReflectedType=[:Type:];staticconstexprInfoM=findMethod(ReflectedType,Name);static_assert(std::meta::parameters_of(M).size()==0&&std::meta::return_type_of(M)==^^void);return[](ReflectedType&instance)->void{instance.[:M:]();};}();[[nodiscard]]constevalInfocreateInvoker(Infotype,StringViewname){returnstd::meta::substitute(^^createInvokerImpl,{std::meta::reflect_constant(type),std::meta::reflect_constant_string(name)});}classFoo{private:// ...public:Foo()=default;voidprintHello()constnoexcept{std::println("Hello, world!");}};intmain(intargc,char*argv[]){Foofoo;// Without reflectionfoo.printHello();// With reflectionautoinvokePrint=[:createInvoker(^^Foo,"printHello"):];invokePrint(foo);return0;}

C#

[edit]

The following is an example inC#:

namespaceWikipedia.Examples;usingSystem;usingSystem.Reflection;classFoo{// ...publicFoo(){}publicvoidPrintHello(){Console.WriteLine("Hello, world!");}}publicclassInvokeFooExample{staticvoidMain(string[]args){// Without reflectionFoofoo=new();foo.PrintHello();// With reflectionObjectfoo=Activator.CreateInstance(typeof(Foo));MethodInfomethod=foo.GetType().GetMethod("PrintHello");method.Invoke(foo,null);}}

Delphi, Object Pascal

[edit]

ThisDelphi andObject Pascal example assumes that aTFoo class has been declared in a unit calledUnit1:

usesRTTI,Unit1;procedureWithoutReflection;varFoo:TFoo;beginFoo:=TFoo.Create;tryFoo.Hello;finallyFoo.Free;end;end;procedureWithReflection;varRttiContext:TRttiContext;RttiType:TRttiInstanceType;Foo:TObject;beginRttiType:=RttiContext.FindType('Unit1.TFoo')asTRttiInstanceType;Foo:=RttiType.GetMethod('Create').Invoke(RttiType.MetaclassType,[]).AsObject;tryRttiType.GetMethod('Hello').Invoke(Foo,[]);finallyFoo.Free;end;end;

eC

[edit]

The following is an example in eC:

// Without reflectionFoofoo{};foo.hello();// With reflectionClassfooClass=eSystem_FindClass(__thisModule,"Foo");Instancefoo=eInstance_New(fooClass);Methodm=eClass_FindMethod(fooClass,"hello",fooClass.module);((void(*)())(void*)m.function)(foo);

Go

[edit]

The following is an example inGo:

import("fmt""reflect")typeFoostruct{}func(fFoo)Hello(){fmt.Println("Hello, world!")}funcmain(){// Without reflectionvarfFoof.Hello()// With reflectionvarfTreflect.Type=reflect.TypeOf(Foo{})varfVreflect.Value=reflect.New(fT)varmreflect.Value=fV.MethodByName("Hello")ifm.IsValid(){m.Call(nil)}else{fmt.Println("Method not found")}}

Java

[edit]

The following is an example inJava:

packageorg.wikipedia.example;importjava.lang.reflect.Method;classFoo{// ...publicFoo(){}publicvoidprintHello(){System.out.println("Hello, world!");}}publicclassInvokeFooExample{publicstaticvoidmain(String[]args){// Without reflectionFoofoo=newFoo();foo.printHello();// With reflectiontry{Foofoo=Foo.class.getDeclaredConstructor().newInstance();Methodm=foo.getClass().getDeclaredMethod("printHello",newClass<?>[0]);m.invoke(foo);}catch(ReflectiveOperationExceptione){System.err.printf("An error occurred: %s%n",e.getMessage());}}}

Java also provides an internal class (not officially in theJava Class Library) inmodulejdk.unsupported,sun.reflect.Reflection which is used bysun.misc.Unsafe. It contains one method,staticClass<?>getCallerClass(intdepth) for obtaining the class making a call at a specified depth.[6] This is now superseded by using the classjava.lang.StackWalker.StackFrame and its methodClass<?>getDeclaringClass().

JavaScript/TypeScript

[edit]

The following is an example inJavaScript:

import'reflect-metadata';// Without reflectionconstfoo=newFoo();foo.hello();// With reflectionconstfoo=Reflect.construct(Foo);consthello=Reflect.get(foo,'hello');Reflect.apply(hello,foo,[]);// With evaleval('new Foo().hello()');

The following is the same example inTypeScript:

import'reflect-metadata';// Without reflectionconstfoo:Foo=newFoo();foo.hello();// With reflectionconstfoo:Foo=Reflect.construct(Foo);consthello:(this:Foo)=>void=Reflect.get(foo,'hello')as(this:Foo)=>void;Reflect.apply(hello,foo,[]);// With evaleval('new Foo().hello()');

Julia

[edit]

The following is an example inJulia:

julia>structPointx::Intyend# Inspection with reflectionjulia>fieldnames(Point)(:x, :y)julia>fieldtypes(Point)(Int64, Any)julia>p=Point(3,4)# Access with reflectionjulia>getfield(p,:x)3

Objective-C

[edit]

The following is an example inObjective-C, implying either theOpenStep orFoundation Kit framework is used:

// Foo class.@interfaceFoo :NSObject-(void)hello;@end// Sending "hello" to a Foo instance without reflection.Foo*obj=[[Fooalloc]init];[objhello];// Sending "hello" to a Foo instance with reflection.idobj=[[NSClassFromString(@"Foo")alloc]init];[objperformSelector:@selector(hello)];

Perl

[edit]

The following is an example inPerl:

# Without reflectionmy$foo=Foo->new;$foo->hello;# orFoo->new->hello;# With reflectionmy$class="Foo"my$constructor="new";my$method="hello";my$f=$class->$constructor;$f->$method;# or$class->$constructor->$method;# with evaleval"new Foo->hello;";

PHP

[edit]

The following is an example inPHP:[7]

// Without reflection$foo=newFoo();$foo->hello();// With reflection, using Reflections API$reflector=newReflectionClass("Foo");$foo=$reflector->newInstance();$hello=$reflector->getMethod("hello");$hello->invoke($foo);

Python

[edit]

The following is an example inPython:

fromtypingimportAnyclassFoo:# ...defprint_hello()->None:print("Hello, world!")if__name__=="__main__":# Without reflectionobj:Foo=Foo()obj.print_hello()# With reflectionobj:Foo=globals()["Foo"]()_:Any=getattr(obj,"print_hello")()# With evaleval("Foo().print_hello()")

R

[edit]

The following is an example inR:

# Without reflection, assuming foo() returns an S3-type object that has method "hello"obj<-foo()hello(obj)# With reflectionclass_name<-"foo"generic_having_foo_method<-"hello"obj<-do.call(class_name,list())do.call(generic_having_foo_method,alist(obj))

Ruby

[edit]

The following is an example inRuby:

# Without reflectionobj=Foo.newobj.hello# With reflectionobj=Object.const_get("Foo").newobj.send:hello# With evaleval"Foo.new.hello"

Rust

[edit]

Rust does not have compile-time reflection in the standard library, but it is possible using some third-party libraries such as "bevy_reflect".[8]

usestd::any::TypeId;usebevy_reflect::prelude::*;usebevy_reflect::{FunctionRegistry,GetTypeRegistration,Reflect,ReflectFunction,ReflectFunctionRegistry,ReflectMut,ReflectRef,TypeRegistry};#[derive(Reflect)]#[reflect(DoFoo)]structFoo{// ...}implFoo{fnnew()->Self{Foo{}}fnprint_hello(&self){println!("Hello, world!");}}#[reflect_trait]traitDoFoo{fnprint_hello(&self);}implDoFooforFoo{fnprint_hello(&self){self.print_hello();}}fnmain(){// Without reflectionletfoo:Foo=Foo::new();foo.print_hello();// With reflectionletmutregistry:TypeRegistry=TypeRegistry::default();registry.register::<Foo>();registry.register_type_data::<Foo,ReflectFunctionRegistry>();registry.register_type_data::<Foo,ReflectDoFoo>();letfoo:Foo=Foo;letreflect_foo:Box<dynReflect>=Box::new(foo);// Version 1: call hello by traitlettrait_registration:&ReflectDoFoo=registry.get_type_data::<ReflectDoFoo>(TypeId::of::<Foo>()).expect("ReflectDoFoo not found for Foo");lettrait_object:&dynDoFoo=trait_registration.get(&*reflect_foo).expect("Failed to get DoFoo trait object");trait_object.print_hello();// Version 2: call hello by function nameletfunc_registry:&FunctionRegistry=registry.get_type_data::<FunctionRegistry>(TypeId::of::<Foo>()).expect("FunctionRegistry not found for Foo");ifletSome(dyn_func)=func_registry.get("print_hello"){letresult:Option<Box<dynReflect>>=dyn_func.call(&*reflect_foo,Vec::<Box<dynReflect>>::new()).ok();ifresult.is_none(){println!("Function called, no result returned (as expected for void return)");}}else{println!("No function named hello found in FunctionRegistry");}}

Xojo

[edit]

The following is an example usingXojo:

' Without reflectionDimfooInstanceAsNewFoofooInstance.PrintHello' With reflectionDimclassInfoAsIntrospection.Typeinfo=GetTypeInfo(Foo)Dimconstructors()AsIntrospection.ConstructorInfo=classInfo.GetConstructorsDimfooInstanceAsFoo=constructors(0).InvokeDimmethods()AsIntrospection.MethodInfo=classInfo.GetMethodsForEachmAsIntrospection.MethodInfoInmethodsIfm.Name="PrintHello"Thenm.Invoke(fooInstance)EndIfNext

See also

[edit]

References

[edit]

Citations

[edit]
  1. ^A Tutorial on Behavioral Reflection and its Implementation by Jacques Malenfant et al.(PDF), unknown, archived fromthe original(PDF) on 21 August 2017, retrieved23 June 2019
  2. ^Brian Cantwell Smith,Procedural Reflection in Programming Languages, Department of Electrical Engineering and Computer Science, Massachusetts Institute of Technology, PhD dissertation, 1982.
  3. ^Brian C. Smith.Reflection and semantics in a procedural languageArchived 2015-12-13 at theWayback Machine. Technical Report MIT-LCS-TR-272, Massachusetts Institute of Technology, Cambridge, Massachusetts, January 1982.
  4. ^Barros, Paulo; Just, René; Millstein, Suzanne; Vines, Paul; Dietl, Werner; d'Amorim, Marcelo; Ernst, Michael D. (August 2015).Static Analysis of Implicit Control Flow: Resolving Java Reflection and Android Intents(PDF) (Report). University of Washington. UW-CSE-15-08-01. RetrievedOctober 7, 2021.
  5. ^Eauvidoum, Ieu; disk noise (October 5, 2021)."Twenty years of Escaping the Java Sandbox".Phrack. Vol. 10, no. 46. RetrievedOctober 7, 2021.
  6. ^"Reflection (Java Platform SE 9)".cr.openjdk.org. OpenJDK. Retrieved10 October 2025.
  7. ^"PHP: ReflectionClass - Manual".www.php.net.
  8. ^"bevy_reflect - Rust".docs.rs. 30 May 2025.

Sources

[edit]

Further reading

[edit]

External links

[edit]
Imperative
Structured
Object-oriented
(comparison,list)
Declarative
Functional
(comparison)
Dataflow
Logic
Domain-
specific
language

(DSL)
Concurrent,
distributed,
parallel
Metaprogramming
Separation
of concerns
Level
Generation
Retrieved from "https://en.wikipedia.org/w/index.php?title=Reflective_programming&oldid=1323485959"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp