“Reflection” is a language’s ability to inspect and dynamically call classes, methods, attributes, etc. at runtime.
For example, all objects in Java has the method getClass, which lets you determine its class even if you don’t know it at compile time (like if you declared it as Object) – this might seem trivial, but such reflection is not by default possible in less dynamic languages such as C++.
Why do we need reflection?
Reflection enables us to:
-
Examine an object’s class at runtime
- Construct an object for a class at runtime
- Examine a class’s field and method at runtime
- Invoke any method of an object at runtime
- Change accessibility flag of Constructor, Method and Field
etc.
Reflection is important since it lets you write programs that does not have to “know” everything at compile time, making them more dynamic, since they can be tied together at runtime. The code can be written against known interfaces, but the actual classes to be used can be instantiated using reflection from configuration files.
Lets see the simple example of forName() method.
class Simple{}
class Test{
public static void main(String args[]){
Class c=Class.forName("Simple");
System.out.println(c.getName());
}
}
For example, say you have an object of an unknown type in Java, and you would like to call a ‘doSomething’ method on it if one exists. Java’s static typing system isn’t really designed to support this unless the object conforms to a known interface, but using reflection, your code can look at the object and find out if it has a method called ‘doSomething’ and then call it if you want to.
So, to give you a code example of this in Java (imagine the object in question is foo) :
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
Getting list of methods in a Class by Reflection
Method[] methods = MyObject.class.getMethods();
for(Method method : methods){
System.out.println("method = " + method.getName());
}
Details which can be accessed by reflection
- Class Name
- Class Modifies (public, private, synchronized etc.)
- Package Info
- Implemented Interfaces
- Superclass
- Constructors
- Fields
- Methods
- Annotations
Reflection allows programmer to access entities in program dynamically. i.e. while coding an application if programmer is unaware about a class or its methods, he can make use of such class dynamically (at run time) by using reflection.
It is frequently used in scenarios where a class name changes frequently. If such a situation arises, then it is complicated for the programmer to rewrite the application and change the name of the class again and again.
Drawbacks
Since everything is done at runtime optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
Usage
- Reflection is used when it is needed to get into the other classes in deeper level. So in most of the cases, these implementors have the container-behavior. For instance, dependency injection is mostly done with the use of reflection
- Remote procedure calling — treat part of a message received over the network as a method name.
- Object-relational mappings — maintain a relationship between fields in an object and columns in a database.
- Interfaces with dynamically typed scripting languages — turn a string value produced by a scripting language into a reference to a field or method on an object.
- Serialization and deserialization — convert field names to string so you can write the object’s fields to a stream and later convert it back into an object.
One useful real-world use of reflection is when writing a framework that has to interoperate with user-defined classes, where th framework author doesn’t know what the members (or even the classes) will be. Reflection allows them to deal with any class without knowing it in advance. For instance, I don’t think it would be possible to write a complex aspect-oriented librory without reflection.
Servlet Mapping in web.xml and Junit annotations are other where reflection is used.
For example, JUnit use reflection to look through methods tagged with the @Test annotation, and then call those methods when running the unit test. (Here is a set of examples of how to use JUnit.)
For web frameworks, product developers define their own implementation of interfaces and classes and put is in the configuration files. Using reflection, it can quickly dynamically initialize the classes required.
For example, Spring uses bean configuration such as:
<bean id="someID" class="com.programcreek.Foo">
<property name="someField" value="someValue" />
</bean>
When the Spring context processes this < bean > element, it will use Class.forName(String) with the argument “com.programcreek.Foo” to instantiate that Class. It will then again use reflection to get the appropriate setter for the < property > element and set its value to the specified value.
The same mechanism is also used for Servlet web applications:
<servlet>
<servlet-name>someServlet</servlet-name>
<servlet-class>com.programcreek.WhyReflectionServlet</servlet-class>
<servlet>