Reflection Java

/*
 This program is a part of the companion code for Core Java 8th ed.
 (http://horstmann.com/corejava)
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see .
 */
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
/**
 * This program uses reflection to spy on objects.
 * 
 * @version 1.11 2004-02-21
 * @author Cay Horstmann
 */
public class ObjectAnalyzerTest {
  public static void main(String[] args) {
    ArrayList squares = new ArrayList();
    for (int i = 1; i <= 5; i++)
      squares.add(i * i);
    System.out.println(new ObjectAnalyzer().toString(squares));
  }
}
class ObjectAnalyzer {
  /**
   * Converts an object to a string representation that lists all fields.
   * 
   * @param obj
   *          an object
   * @return a string with the object's class name and all field names and
   *         values
   */
  public String toString(Object obj) {
    if (obj == null)
      return "null";
    if (visited.contains(obj))
      return "...";
    visited.add(obj);
    Class cl = obj.getClass();
    if (cl == String.class)
      return (String) obj;
    if (cl.isArray()) {
      String r = cl.getComponentType() + "[]{";
      for (int i = 0; i < Array.getLength(obj); i++) {
        if (i > 0)
          r += ",";
        Object val = Array.get(obj, i);
        if (cl.getComponentType().isPrimitive())
          r += val;
        else
          r += toString(val);
      }
      return r + "}";
    }
    String r = cl.getName();
    // inspect the fields of this class and all superclasses
    do {
      r += "[";
      Field[] fields = cl.getDeclaredFields();
      AccessibleObject.setAccessible(fields, true);
      // get the names and values of all fields
      for (Field f : fields) {
        if (!Modifier.isStatic(f.getModifiers())) {
          if (!r.endsWith("["))
            r += ",";
          r += f.getName() + "=";
          try {
            Class t = f.getType();
            Object val = f.get(obj);
            if (t.isPrimitive())
              r += val;
            else
              r += toString(val);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      r += "]";
      cl = cl.getSuperclass();
    } while (cl != null);
    return r;
  }
  private ArrayList visited = new ArrayList();
}