Sunday, March 29, 2009

Demonstrating Basic Understanding of Reflection Concepts During an Interview

When interviewing, I like to ask about reflection. It is a universal object oriented concept that will give you (the interviewer) insight into the depth of knowledge the interviewee has about object oriented concepts. Aside from knowing what reflection does, having the interviewee speak to an example is another good indicator that they understand. The following problem will likely suffice for a general question:

Given a map of name-value pairs, how would you blindly set the correct values on a contain object that makes more sense to hold those values? For example, suppose you have a map of location / address data. A simple "Location" would have a address, city, state, postal, etc, modifiers and accessors. How would you load the "Location" object from the map values using reflection? What would you do with the additional data that is not directly accessible on the "Location" object?

Code aside, I would follow the following steps:
  1. Look up the setters on the location object using the getMethods method
  2. Match the map keys up with the results of the getMethods call. To do this, you will have to assume the map keys are the field names and "set" + "field name" is the setter on that field. You will also have to adjust the casing of the field name. For example, something simple would be fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1).
  3. If the "Location" object contains a "set" + "field name", set the value for it. To do this, you can get the method object directly for that setter, location.getClass().getMethod(setterName, classParm). Then invoke the method to set the value you want for that field, method.invoke(location, valueArg).
  4. If the "Location" object does not contain a setter for the given field name, I would extend the "Location" object to have an "extended data" map for storing extra location values.
Some Code...

Checking for a method name on an object:
String classField = getClassFieldName(nextField);
Method[] methods = Location.class.getMethods();
for(int i=0; i

Invoking method via reflection on object:
Location location = new Location();
Class[] classParm = {String.class};
String setterName = "set" + getClassFieldName(nextKey);
Method method = location.getClass().getMethod(setterName, classParm);
String[] valueArg = {nextValue};
method.invoke(location, valueArg);

Share on Twitter