在程序中log信息可以跟踪程序的执行情况,大多时候我们需要将一个pojo,list或是一个自定义结构中的信息打印出来,这样可以检查信息是否是我们所需要的,通常情况下这个就是需要遍历了,效率不高且不通用,以下为一个通用的结构打印的代码,以供参考。
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TypeUtil {
/**
* Returns a string holding the contents of the passed object,
*
* @param scope
* String
* @param parentObject
* Object
* @param visitedObjs
* List
* @return String
*/
private static String complexTypeToString(String scope, Object parentObject, List visitedObjs) {
StringBuffer buffer = new StringBuffer("");
try {
//
// Ok, now we need to reflect into the object and add its child
// nodes...
//
Class cl = parentObject.getClass();
while (cl != null) {
processFields(cl.getDeclaredFields(), scope, parentObject, buffer, visitedObjs);
cl = cl.getSuperclass();
}
} catch (IllegalAccessException iae) {
buffer.append(iae.toString());
}
return (buffer.toString());
}
/**
* Method processFields
*
* @param fields
* Field[]
* @param scope
* String
* @param parentObject
* Object
* @param buffer
* StringBuffer
* @param visitedObjs
* List
* @throws IllegalAccessException
*/
private static void processFields(Field[] fields, String scope, Object parentObject, StringBuffer buffer, List visitedObjs) throws IllegalAccessException {
for (int i = 0; i < fields.length; i++) {
//
// Disregard certain fields for IDL structures
//
// if (fields[i].getName().equals("__discriminator")
// || fields[i].getName().equals("__uninitialized")) {
// continue;
// }
//
// This allows us to see non-public fields. We might need to deal
// with some
// SecurityManager issues here once it is outside of VAJ...
//
fields[i].setAccessible(true);
if (Modifier.isStatic(fields[i].getModifiers())) {
//
// Ignore all static members. The classes that this dehydrator
// is
// meant to handle are simple data objects, so static members
// have no
// bearing....
//
} else {
buffer.append(typeToString(scope + "." + fields[i].getName(), fields[i].get(parentObject), visitedObjs));
}
}
}
/**
* Method isCollectionType
*
* @param obj
* Object
* @return boolean
*/
public static boolean isCollectionType(Object obj) {
return (obj.getClass().isArray() || (obj instanceof Collection) || (obj instanceof Hashtable) || (obj instanceof HashMap) || (obj instanceof HashSet)
|| (obj instanceof List) || (obj instanceof AbstractMap));
}
/**
* Method isComplexType
*
* @param obj
* Object
* @return boolean
*/
public static boolean isComplexType(Object obj) {
if (obj instanceof Boolean || obj instanceof Short || obj instanceof Byte || obj instanceof Integer || obj instanceof Long || obj instanceof Float
|| obj instanceof Character || obj instanceof Double || obj instanceof String) {
return false;
} else {
Class objectClass = obj.getClass();
if (objectClass == boolean.class || objectClass == Boolean.class || objectClass == short.class || objectClass == Short.class || objectClass == byte.class
|| objectClass == Byte.class || objectClass == int.class || objectClass == Integer.class || objectClass == long.class || objectClass == Long.class
|| objectClass == float.class || objectClass == Float.class || objectClass == char.class || objectClass == Character.class || objectClass == double.class
|| objectClass == Double.class || objectClass == String.class) {
return false;
}
else {
return true;
}
}
}
/**
* Returns a string holding the contents of the passed object,
*
* @param scope
* String
* @param obj
* Object
* @param visitedObjs
* List
* @return String
*/
private static String collectionTypeToString(String scope, Object obj, List visitedObjs) {
StringBuffer buffer = new StringBuffer("");
if (obj.getClass().isArray()) {
if (Array.getLength(obj) > 0) {
for (int j = 0; j < Array.getLength(obj); j++) {
Object x = Array.get(obj, j);
buffer.append(typeToString(scope + "[" + j + "]", x, visitedObjs));
}
} else {
buffer.append(scope + "[]: empty\n");
}
} else {
boolean isCollection = (obj instanceof Collection);
boolean isHashTable = (obj instanceof Hashtable);
boolean isHashMap = (obj instanceof HashMap);
boolean isHashSet = (obj instanceof HashSet);
boolean isAbstractMap = (obj instanceof AbstractMap);
boolean isMap = isAbstractMap || isHashMap || isHashTable;
if (isMap) {
Set keySet = ((Map) obj).keySet();
Iterator iterator = keySet.iterator();
int size = keySet.size();
if (size > 0) {
for (int j = 0; iterator.hasNext(); j++) {
Object key = iterator.next();
Object x = ((Map) obj).get(key);
buffer.append(typeToString(scope + "[\"" + key + "\"]", x, visitedObjs));
}
} else {
buffer.append(scope + "[]: empty\n");
}
} else if (/* isHashTable || */
isCollection || isHashSet /* || isHashMap */
) {
Iterator iterator = null;
int size = 0;
if (obj != null) {
if (isCollection) {
iterator = ((Collection) obj).iterator();
size = ((Collection) obj).size();
} else if (isHashTable) {
iterator = ((Hashtable) obj).values().iterator();
size = ((Hashtable) obj).size();
} else if (isHashSet) {
iterator = ((HashSet) obj).iterator();
size = ((HashSet) obj).size();
} else if (isHashMap) {
iterator = ((HashMap) obj).values().iterator();
size = ((HashMap) obj).size();
}
if (size > 0) {
for (int j = 0; iterator.hasNext(); j++) {
Object x = iterator.next();
buffer.append(typeToString(scope + "[" + j + "]", x, visitedObjs));
}
} else {
buffer.append(scope + "[]: empty\n");
}
} else {
//
// theObject is null
buffer.append(scope + "[]: null\n");
}
}
}
return (buffer.toString());
}
/**
* Method typeToString
*
* @param scope
* String
* @param obj
* Object
* @param visitedObjs
* List
* @return String
*/
private static String typeToString(String scope, Object obj, List visitedObjs) {
if (obj == null) {
return (scope + ": null\n");
} else if (isCollectionType(obj)) {
return collectionTypeToString(scope, obj, visitedObjs);
} else if (isComplexType(obj)) {
if (!visitedObjs.contains(obj)) {
visitedObjs.add(obj);
return complexTypeToString(scope, obj, visitedObjs);
} else {
return (scope + ": \n");
}
} else {
return (scope + ": " + obj.toString() + "\n");
}
}
/**
* The typeToString() method is used to dump the contents of a passed object
* of any type (or collection) to a String. This can be very useful for
* debugging code that manipulates complex structures, such as the
* Middleware BIS EJBs.
*
* @param scope
* @param obj
*
* @return String
*
*/
public static String typeToString(String scope, Object obj) {
if (obj == null) {
return (scope + ": null\n");
} else if (isCollectionType(obj)) {
return collectionTypeToString(scope, obj, new ArrayList());
} else if (isComplexType(obj)) {
return complexTypeToString(scope, obj, new ArrayList());
} else {
return (scope + ": " + obj.toString() + "\n");
}
}
public static String checkValue(String s) {
if (s == null)
return "";
if (s.startsWith("$")) {
s = "";
}
return s;
}
public static boolean stringIsEmpty(String input) {
if (input != null && !input.trim().equalsIgnoreCase("")) {
return false;
}
return true;
}
}
使用方法很简单:比如要打印User这个对象的内容:
TypeUtil.typeToString("User:",user);
注意:此方法确实可以打印复杂数据的结构,但是如果属于层次较为深的或是十分复杂的那一种,不推荐打印,因为如果数据量大且复杂这种遍历会吃掉服务器大量内存而导致OOM,所以此方法用于在log中检查中小数据结构的层次与正确性比较合适。