package org.fanhongtao.lang; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * 实现将一个Java对象的内容以方便阅读的方式转换成字符串。<br> * 注意,因为使用了StringBuilder,这个类不是线程安全的,只能在一个线程内部使用这个类。<br> * 通常的用法是在需要时临时定义一个Dump对象,然后调用其toString方法。如: * System.out.println(new Dump().toString(object)); * * @author Dharma * @created 2010-2-28 */ public class Dump { /** 打印信息的缺省层数 */ public static final int DEFAULT_LEVEL = 3; private static final String CRLF = System.getProperty("line.separator"); /** 保存转换过程中的字符串 */ private StringBuilder buf = null; /** 打印对象的最大层数 */ private int maxLevel = -1; /** 记录每个打印的对象,防止对象相互引用而造成死循环 */ private Set<Integer> path = new HashSet<Integer>(); public Dump() { this(DEFAULT_LEVEL); } public Dump(int maxLevel) { buf = new StringBuilder(1024); this.maxLevel = maxLevel; } // public String toString(int i) // { // return Integer.toString(i); // } public String toString(Object obj) { return toString(null, obj); } public String toString(String prefix, Object obj) { if (null != prefix) { buf.append(prefix).append(CRLF); } dumpObj(obj); return buf.toString(); } private void dumpObj(Object obj) { if (path.size() > maxLevel) { buf.append("Too many level!"); return; } if (null == obj) { buf.append("null"); return; } else if ((obj instanceof Number) || (obj instanceof String) || (obj instanceof Character) || (obj instanceof Boolean)) { buf.append(obj); return; } // 判断对象是否重复 int id = System.identityHashCode(obj); if (path.contains(id)) { buf.append("Object is reentered!"); return; } path.add(id); begin(); if (obj instanceof List) { dumpList((List<?>) obj); } else if (obj instanceof Map) { dumpMap((Map<?, ?>) obj); } else if (obj instanceof byte[]) { dumpByteArray((byte[]) obj); } else { Class<?> objClass = obj.getClass(); if (objClass.isArray()) { dumpArray((Object[]) obj); } else { dumpClass(obj, objClass); } } end(); path.remove(id); } /** * 将一个Map对象转换字符串 * @param map */ private void dumpMap(Map<?, ?> map) { Iterator<?> iter = map.entrySet().iterator(); // while (iter.hasNext()) for (int i = 0; i < map.entrySet().size(); i++) { if (i != 0) { buf.append(", ").append(CRLF); } Map.Entry<?, ?> entry = (Map.Entry<?, ?>) iter.next(); buf.append("key: "); dumpObj(entry.getKey()); buf.append(", value: "); dumpObj(entry.getValue()); } } /** * 将一个List对象转换字符串 * @param list */ private void dumpList(List<?> list) { for (int i = 0; i < list.size(); i++) { if (i != 0) { buf.append(", ").append(CRLF); } dumpObj(list.get(i)); } } /** * 将一个数组对象转换字符串 * @param objs 待转换的数组 */ private void dumpArray(Object[] objs) { for (int i = 0; i < objs.length; i++) { if (i != 0) { buf.append(", ").append(CRLF); } dumpObj(objs[i]); } } private void dumpByteArray(byte[] bytes) { buf.append(StringUtils.toHexString(bytes)); } /** * 将一个自定义的类对象转换字符串 * @param obj 待转换类对象 * @param objClass 该对象对应的类定义 */ private void dumpClass(Object obj, Class<?> objClass) { Field[] fields = objClass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (i != 0) { buf.append(", "); // .append(CRLF); } Field field = fields[i]; field.setAccessible(true); // 关闭java的访问修饰符检测 Object value; try { value = field.get(obj); } catch (Exception e) { e.printStackTrace(); continue; } buf.append(field.getName()).append('='); dumpObj(value); } } private void begin() { buf.append('{'); } private void end() { buf.append('}'); } }