What is Reflection in Programming?
Reflective programming is a mechanism that lets a process introspective capabilities. The reflection APIs built into programming languages allow you to inspect code at runtime. You can use this ability to learn about the surrounding codebase and its contents. Reflections often talked about in the context of object-oriented programming. You often use reflection to discover codebase entities at runtime. The languages reflection API will let you inspect classes, methods, properties, and types from within your system. This lets you build more dynamic functionality. Systems which utilize reflection are able to interrogate and modify their own environments. This is where reflection differs from plain value introspection. A language with full reflection support will permit codebase modification at runtime, effectively allowing the source to rewrite aspects of itself. An Example of Reflection  One common use for reflection is during testing. Reflection can help you mock classes by exposing their internal behaviors. A class method thats protected or private wouldnt usually be testable; using reflection, you can override the visibility constraint so it becomes public in your unit tests. class Test { protected int $Value ; public function __construct ( int $Value ) { $this -> Value = $Value ; } protected function computeValue ( ) : int { return ( $this -> Value * 2 ) ; } } /** * Without Reflection */ $t = new Test ( 10 ) ; // Error - the method isn't publicly accessible assert ( $t -> computeValue ( ) === 20 ) ; /** * Using Reflection */ $reflectionMethod = new ReflectionMethod ( Test :: CLASS , "computeValue" ) ; $reflectionMethod -> setAccessible ( true ) ; $t = new Test ( 10 ) ; // This now works! assert ( $reflectionMethod -> invoke ( $t ) === 20 ) ;  In this example using PHP, the Test class defines a protected method thats used internally. As the methods performing a calculation, you might want to unit test it. You cant call the method externally but PHPs Reflection API lets you bypass the visibility constraints. A ReflectionMethod instance provides information about the method and lets you invoke a modified version. While this is helpful, you should be conscious that it can be misused. Widespread use of reflection in testing is often indicative of bigger problems in your codebase. It implies the class interface is overly restrictive and unsuited to its responsibilities. In many cases, its more appropriate to refactor the protected method out into a new class that exposes its own public interface. Heres how that might look for the example shown above:  class Calculator { public function computeValue ( ) : int { return ( $this -> Value * 2 ) ; } } class Test { protected int $Value ; protected Calculator $Calculator ; public function __construct ( int $Value , Calculator $Calculator ) { $this -> Value = $Value ; $this -> Calculator = $Calculator ; } }  The calculator component is now its own standalone unit with a testable public interface. This goes hand-in-hand with dependency injection  the Test class is now given a Calculator which implements the calculation logic. Using Reflection With Unpredictable Values  Reflections also useful when youre writing generic code within a framework. You might need to interface with user-supplied types which you cant anticipate. Reflection can help when you dont know what methods and properties a type exposes. You can obtain a picture of the types functionality without any previous knowledge of its source. This is useful in the context of logging and error reporting components which might want to dump the member list of any class theyre passed. Data marshalling systems are often implemented in this way too. Imagine a marshaller that takes a class and converts it to a JSON representation. You might define a convention that any method thats prefixed with get and ends with Json (e.g. getUserJson() ) should be called by the marshaller and added to its output. Reflection provides the mechanism to get the list of methods. Youd then implement logic to identify the ones you should call. Reflection, Compilation, and Assembles  Reflection provides additional capabilities in compiled languages that utilize linked libraries and assemblies. Reflection APIs let you inspect the contents of loaded assemblies. In languages such as C#, you can dynamically load additional assemblies by utilizing Reflection APIs. This approach can be useful if youre implementing a plugin system with user-supplied assemblies. Your program wont know which plugins are available when its compiled. Each time it launches, itll need to check the filesystem to find available plugin assemblies. Once a plugins been found, Reflection provides a mechanism to load and instantiate its members. You could inspect the plugin, find the classes it provides and register it with your application. Further inspection of the assembly might provide the plugins name and version for display in your logs and user interface. Reflection can also be used to switch out assemblies based on external configuration. Lets say youre writing an application that saves image files to storage. You might have a LocalStorageDriver , FtpStorageDriver and AmazonS3StorageDriver , each contained in its own assembly (a .dll in C#). Using reflection, you could offer a storage driver key in your systems configuration file. The appropriate assembly would be loaded dynamically based on your config files value. Youd inspect the assembly to discover the class that implements your StorageDriver interface. This approach lets you switch out components of your system at runtime. You dont need to recompile or restart your program to change between assemblies. This gives you increased flexibility and assists the implementation of configuration directives. Eval Statements  Reflection is closely related to eval . Many programming languages provide a way to execute dynamic string values as source code. Eval is a permutation of reflection with almost limitless power. It lets you create and run new code within a live program. This poses a potentially catastrophic security issue if user input gets fed into the eval string. An eval statement should be used when youre left with no other options. You need to make sure the statement is executed in a restricted context which cant be exploited by users. Remember that a successful code injection would give an attacker the same powers as your regular application code. Conclusion  Reflection is a programming technique that gives code introspective abilities. Effective use of reflection lets you write more dynamic systems and benefit from increased automation. You can also use reflection to unit test otherwise unreachable private code. You do need to exercise caution. Reflection APIs in programming languages are powerful so with them comes responsibility. The biggest issue is reflections ability to subvert the protections provided by your programming language. Reflection permits the existence of scenarios that would otherwise be impossible, such as writes to immutable variables and widespread public use of private methods. You should be able to trust your code to respect the rules of its language. Use of the reflection APIs must therefore be carefully considered and scoped to specific sections of your system.