Some useful use cases for Java Reflection
Posted on September 14, 2014 • 2 minutes • 394 words
While most will recommend you not to use Reflection because:
-
Lose ability to refactoring because you hard-code the name of class/method as String.
-
Lower runtime performance,
-
No compile time safety check.
However, there’re many cases Reflection can become very useful that it pros might outweight its cons. Or it’s just cool to show colleagues some new cool tips.
Easier to implement toString() method for debugging
You can use Reflection to loop through an Object’s attribute and print it out instead of using StringBuilder to append it yourself. This feature is available in Apache Common Lang . Or you can write it yourself if all you need is this method.
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
Note: This is actually not used often because modern IDE(IntelliJ, Eclipse, NetBean, …) already has ‘generator’ for this kind of thing.
Create object/call method using name
This is one of the reasons why Reflection exists in the first place. It’s useful in case like you have some configuration stored in database and you want to create object using class name (e.g.: like building cache using class name and table name on startup).
Or another case would be like: You get tired of calling .add
for BigDecimal
so you write a function to sum it up, taking an ArrayList of BigDecimal as parameter. But it’s not convenient because in reality, you have object of other data type and you will have to create the ArrayList of BigDecimal by looping through the collection. This is when Reflection comes in handy. You can use Reflection to create a function, passing a collection of anything and a method name to get the BigDeicmal value out.
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> BigDecimal getSumBigDecimal(ArrayList<T> bcArr, String methodName) {
BigDecimal sum = BigDecimal.ZERO;
if (null != bcArr && bcArr.size() != 0 && !StringUtil.isEmpty(methodName)) {
try {
T firstItem = bcArr.get(0);
Class klass = firstItem.getClass();
Method method = klass.getMethod(methodName);
for (T each : bcArr) {
BigDecimal bc = (BigDecimal) method.invoke(each);
sum = sum.add(bc == null ? BigDecimal.ZERO : bc);
}
}
catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
// do what you must here, I'm catching because it's an example
e.printStackTrace();
}
}
return sum;
}
}
Reflection is cool and all but please use it with care. Make sure the pros outweight the cons. Know what you’re doing.