A Reflective toString Method for Java
Often times I find the debugger to onerous for viewing DAOs. They usually contain lots, and lots of attributes and viewing those attributes is tedious, at least in my opinion. I prefer looking at them as text output. With text I can quickly scan through them or copy them or do any number of other things. With the debugger, their values reside strictly in the debugger.
My first reaction has been to create a toString method. This works rather well but it too is tedious. So I’ve created a toString method that uses reflection to create the output. The code for this method is located at the bottom of this post.
Some things to note:
- This code has been created for my own use. Therefore you won’t have some of the objects I reference.
- This code is free for all uses. If you’d like to use it commercially or for your own pet projects feel free to do so. Although I wouldn’t mind a mention (or a link) in the Javadoc or on the application’s web page if you see fit to do so.
- This code is by no means feature complete. For example, I imagine it could be recursive so that when an object is encountered, this method is called instead of the Object’s toString method.
- I also notice that my escape characters are no longer escaped. This means that you’ll have to add your own backslashes.
- This code uses StringBuffer when StringBuilder would be more appropriate. I used StringBuffer because of constraints that were put on me when I originally developed it. (If you’re interested in the differences between these two check out: http://forum.java.sun.com/thread.jspa?threadID=652378)
The Code
public static String toString(Object a_oToConvert)
{
if(a_oToConvert == null)
{
return "Object is null";
}
StringBuffer sb = new StringBuffer();
sb.append("n");
sb.append("t" + Util.DASHES + "n");
sb.append("t" + a_oToConvert.getClass().getName() + "n");
sb.append("t" + Util.DASHES + "n");
Class cls = a_oToConvert.getClass();
Field[] arrFields = cls.getDeclaredFields();
for(int idxField = 0; idxField < arrFields.length; idxField++)
{
Field fldCurrent = arrFields[idxField];
String sName = fldCurrent.getName();
Object oVal = new String("---");
char[] arrChars = sName.toCharArray();
char[] arrMod = new char[arrChars.length];
for(int x = 3; x < arrChars.length; x++)
{
arrMod[x - 3] = arrChars[x];
}
String sFirstChar = new String("" + arrMod[0]);
arrMod[0] = sFirstChar.toUpperCase().toCharArray()[0];
String sGetMethod = "get" + new String(arrMod).trim();
try
{
Method methGet = cls.getMethod(sGetMethod, null);
if(methGet != null)
{
oVal = methGet.invoke(a_oToConvert, null);
}
if(oVal == null)
{
oVal = new String("Value is null");
}
else
{
if(oVal instanceof List)
{
oVal = "List Size: " + ((List)oVal).size();
}
}
}
catch(NoSuchMethodException nme)
{
oVal = "No such getter - " + sGetMethod + "()";
}
catch(IllegalAccessException iae)
{
oVal = "Not public - " + sGetMethod + "()";
}
catch(InvocationTargetException ite)
{
oVal = "ITE" + ite.getLocalizedMessage();
}
sb.append("t" + Util.beautify(sName, oVal.toString()) + "n");
}
sb.append("t" + Util.DASHES);
return sb.toString();
}