Sunday, November 17, 2013

Resolving generic method return types

Java supports generic/parameterized return types:
public <t> T anyType();
A method with a generic return type like above is now expected to return different types depending on its caller. For example -
String string = anyType();
expects "anyType()" to return a String. Whereas
Integer i = anyType();
expects "anyType()" to return an Integer.  There does not appear to ber a way of determining a method's expected return type at runtime.  To get around this, many APIs tend to specify the expected return type by describing it in method parameters - for example:
public <t> T anyType(Class<T> type);
public <T> T getBean(String beanName,Class<T> beanType);
I put together a library that provides an alternative -
public <T> T anyType(){
  Class<?> myReturnType = Resolver.getConcreteReturnType();
  ..
}
The library works by inspecting a method's call stack. The call stack typically includes class names, method names, and line numbers. Using these, the library locates the code surrounding method invocations using the ASM bytecode manipulation library and inspects it for "CHECKCAST" operations. The found type is the expected return type of the parameterized method. Extracting parameterized return types (e.g. Map<String,List<Integer>>) is a little trickier but also possible.

Instead of going with the google code route to share the project like I'm used to, I've decided to give github a try. I've also set up continuous integration using drone.io - so far, it's been an excellent experience. Read more over at https://github.com/ProfessorEugene/rrd-generics-inspector !