Recently I was discussing with friends about different programming languages. Of course, many have different experiences in their career. In this discussion, the topic of Object Reflection in Java arose. In fact, what is it good for and where is it used?
First, let's see how the term Object Reflection is defined: With Object Reflection Java offers a feature to get reflective information about Java classes and object. Furthermore, it enables the developer to execute operations on Java classes at runtime.
Sounds good? No? What is meant with reflective information? To describe this fact in an easy way:
- We can see field and method information of the class at runtime (when your application is running)
- We can access fields and methods without access restrictions (private, protected)
- Since the constructor belongs to the class as well, we can create new instances of a class
How can those points help in software development in Java?
With the field and class information at runtime, we can easily stop the application at a certain point and have a look at the state of a class. You will recognize this as your daily debugging process. This means that your IDE is maybe using exactly this feature to give you more information about the state of your class or application.
By removing the restrictions to field and methods access levels we can modify classes, too. Sometimes it can be useful (but of course can be dangerous as well).
In the combination of all three points, we can write extensible/configurable libraries. Think of the following scenario: You have implemented a library which can calculate a route from one city to another. You define the main routing algorithm to be MyLibrary.RoutingStrategy. As soon as you publish your library it can only use this RoutingStrategy. To make your library configurable, you can provide a configuration where you set your RoutingStrategy as default but can be set to something else which implements your API:
// The given string can come from a config (yml, xml, ...) String strategyClass = "ThirdPartyProject.FastestRouteStrategy"; // Get the configured class Class strategyDefinition = Class.forName(strategyClass); Constructor strategyDefinition.getConstructor(); IRoutingStrategy strategy = strategyDefinition.newInstance();
The example above demonstrates how we can create classes we don't know about when we develop libraries. But we can call methods as well. This would look like this:
// Get the configured class Class strategyDefinition = Class.forName(strategyClass); Method method = strategyDefinition.getDeclaredMethod("calculate"); Constructor strategyDefinition.getConstructor(); IRoutingStrategy strategy = strategyDefinition.newInstance(); // Invoke method on our class Route route = method.invoke(strategy);
This both examples show the most basic use cases of Object Reflection in Java. Yes, there are more complex examples of accessing API information or reading inner classes or objects. But we won't cover this topics in this blog post.
I hope you find this blog post useful. If you have any questions or comments, please feel free to use the comment area below.