打印自定义类中的属性方法值,会自动调用类的toString()方法,如果是基本类型或其对应的包装类型,显示出来的值是正常的
而如果是类对象(包括自定义的类).如果不重写toString()方法,则打印出来的是一个地址,无法看出其真实有用的值
所以,经常会遇到要打印类的有效信息,不得不去重写每个类的toString()方法,比较麻烦
简单的办法就是写一个工具类,每次调用这个工具会很方法
原理:将所有的类,包括自定义的类,也就是非基本类型的类,全部都转为key-value的map结构,最后再调用map的toString()方法.
结构包括:LoggerUtils.java 工具类
Log.java 日志注解类
具体代码如下:
LoggerUtils.java
/**
* @author lip
* @date 2015年7月13日 下午4:41:07
*/
package com.lpayit;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import com.lpayit.annotation.Log;
/**
* @author lip
* @date 2015年7月13日 下午4:41:07
*/
public class LoggerUtils {
/**自定义包前缀*/
private static final String PKG_PREFIX = "com.lpayit";
/**递归最大层级*/
private static final int MAX_CALL_LEVEL = 5;
/**
* 获取所有字段,包括父类
* @author lip
* @date 2015年7月13日 下午4:39:11
* @param clazz
* @return
*/
private static List<Field> getAllDeclareFields(Class<?> clazz) {
List<Field> fieldList = new ArrayList<Field>();
Map<String, Field> fieldMap = new HashMap<String, Field>();
for(;clazz != Object.class;clazz = clazz.getSuperclass()){
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
if(!fieldMap.containsKey(field.getName())){
fieldMap.put(field.getName(), field);
}
}
}
fieldList = new ArrayList<Field>(fieldMap.values());
return fieldList;
}
/**
* 判断是否为基本类型
* @author lip
* @date 2015年7月13日 下午4:38:54
* @param obj
* @return
*/
private static Boolean isPrimitive(Object obj){
if(obj == null){
return true;
}
if(obj.getClass().isPrimitive()){
return true;
}
if(obj instanceof Byte){
return true;
}
if(obj instanceof Short){
return true;
}
if(obj instanceof Integer){
return true;
}
if(obj instanceof Long){
return true;
}
if(obj instanceof Float){
return true;
}
if(obj instanceof Double){
return true;
}
if(obj instanceof Character){
return true;
}
if(obj instanceof Boolean){
return true;
}
if(obj instanceof String){
return true;
}
if(obj instanceof BigDecimal){
return true;
}
if(obj instanceof Date){
return true;
}
if(obj instanceof Enum){
return true;
}
return false;
}
/**
* 转化为String
* 暂只支持类型Map,Collection,Array,自定义类型(com.lpayit包下的所有类)
* @author lip
* @date 2015年7月14日 下午2:00:56
* @param obj
* @return
*/
public static String reflectionToString(Object obj){
return reflectionToString(obj, true);
}
/**
* 转化为String
* 暂只支持类型Map,Collection,Array,自定义类型(com.lpayit包下的所有类)
* @author lip
* @date 2015年7月15日 上午9:33:01
* @param obj
* @param containNull
* @return
*/
public static String reflectionToString(Object obj,boolean containNull){
Object objResult = reflectionToString(obj, containNull ,1);
if(objResult == null){
return null;
}
return objResult.toString();
}
/**
* 组装数据
* @author lip
* @date 2015年7月15日 上午9:33:09
* @param obj
* @param containNull
* @param level
* @return
*/
@SuppressWarnings("unchecked")
private static Object reflectionToString(Object obj,boolean containNull,int level){
/**基本数据类型的情况*/
if(isPrimitive(obj)){
return obj;
}
/**Map的情况*/
if(obj instanceof Map){
Map<Object,Object> objMap = (Map<Object, Object>) obj;
Map<Object,Object> map = new TreeMap<Object,Object>();
for(Object objKey : objMap.keySet()){
/**为基本类型时,包括String*/
if(isPrimitive(objMap.get(objKey))){
map.put(objKey,objMap.get(objKey));
}else {
map.put(objKey,changeToMap(objMap.get(objKey), containNull,level+1));
}
}
return map;
}
/**List的情况*/
if(obj instanceof Collection<?>){
Collection<Object> objList = (Collection<Object>) obj;
List<Object> list = new ArrayList<Object>();
for(Object objListVar : objList){
/**为基本类型时,包括String*/
if(isPrimitive(objListVar)){
list.add(objListVar);
}else {
list.add(changeToMap(objListVar,containNull,level+1));
}
}
return list;
}
/**数组的情况*/
if(obj instanceof Object[]){
List<Object> objList = Arrays.asList((Object[]) obj);
List<Object> list = new ArrayList<Object>();
for(Object objListVar : objList){
/**为基本类型时,包括String*/
if(isPrimitive(objListVar)){
list.add(objListVar);
}else {
list.add(changeToMap(objListVar,containNull,level+1));
}
}
return list;
}
/**自定义数据类型的情况*/
if(obj.getClass().getName().startsWith(PKG_PREFIX)){
return changeToMap(obj, containNull, level);
}
return obj;
}
/**
* 获取注解
* @author lip
* @date 2015年7月14日 下午6:42:33
* @param field
* @return
*/
private static Log getLogAnno(Field field){
Log log = null;
Annotation[] annotations = field.getDeclaredAnnotations();
if(annotations != null && annotations.length > 0){
for(Annotation annoTmp : annotations){
if(annoTmp instanceof Log){
log = (Log) annoTmp;
break;
}
}
}
return log;
}
/**
* 将自定义类转为Map类型,包括内部的所有
* @author lip
* @date 2015年7月13日 下午4:55:12
* @param obj
* @param containNull
* @param level 最大递归级别,防止死递归
* @return
*/
@SuppressWarnings("unchecked")
private static Map<String,Object> changeToMap(Object obj,boolean containNull,int level){
if(level++ > MAX_CALL_LEVEL){
Map<String,Object> result = new TreeMap<String, Object>();
result.put(obj.getClass().getSimpleName(), obj);
return result;
}
/**对像为空*/
if(obj == null){
return null;
}
/**存放返回结果*/
Map<String, Object> resultMap = new TreeMap<String, Object>();
List<Field> Fields = getAllDeclareFields(obj.getClass()); // 获取所有字段(包括所有父类,当有多个父类时,以子类为准)
for(Field field : Fields){
field.setAccessible(true);
String fieldName = field.getName();
if(Modifier.isStatic(field.getModifiers()) ){
continue; // 忽略静态属性
}
Log log = getLogAnno(field);
if(log != null){
if(!log.isLog()){
continue; // 不记录日志(@log(isLog=false))
}
if(!StringUtils.isBlank(log.name())){
fieldName = log.name(); // 自定义fieldName
}
}
try {
Object objVar = field.get(obj); // 获取字段返回值
if(objVar == null){
if(!containNull){ // 如果containNull 为false,则不获取为null的值
continue;
}
}
if(objVar != null){
String clazzName = objVar.getClass().getName();
if(clazzName == null || "".equals(clazzName.trim())) continue;
/**为基本类型时,包括String等*/
if(isPrimitive(objVar)){
resultMap.put(fieldName, objVar);
}else if(clazzName.startsWith(PKG_PREFIX)){
/**指定包下的类*/
objVar = changeToMap(objVar,containNull,level);
}else if(objVar instanceof Map){
/**Map的情况*/
Map<Object,Object> objMap = (Map<Object, Object>) objVar;
Map<Object,Object> map = new TreeMap<Object,Object>();
for(Object objKey : objMap.keySet()){
/**为基本类型时,包括String*/
if(isPrimitive(objMap.get(objKey))){
map.put(objKey,objMap.get(objKey));
}else {
map.put(objKey,changeToMap(objMap.get(objKey), containNull,level));
}
}
objVar = map;
}else if(objVar instanceof Collection<?>){
/**List的情况*/
Collection<Object> objList = (Collection<Object>) objVar;
List<Object> list = new ArrayList<Object>();
for(Object objListVar : objList){
/**为基本类型时,包括String*/
if(isPrimitive(objListVar)){
list.add(objListVar);
}else {
list.add(changeToMap(objListVar,containNull,level));
}
}
objVar = list;
}else if(objVar instanceof Object[]){
/**数组的情况*/
List<Object> objList = Arrays.asList((Object[]) objVar);
List<Object> list = new ArrayList<Object>();
for(Object objListVar : objList){
/**为基本类型时,包括String*/
if(isPrimitive(objListVar)){
list.add(objListVar);
}else {
list.add(changeToMap(objListVar,containNull,level));
}
}
objVar = list;
}
}
resultMap.put(fieldName, objVar);
} catch (Exception e) {
e.printStackTrace();
}
}
return resultMap;
}
}
Log.java
package com.lpayit.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.FIELD})
public @interface Log {
/**是否记录日志*/
boolean isLog() default true;
String name() default "";
}