Java对象的打印_java反射原理制作对象打印工具

主要运用java反射原理,格式化输出java对象属性值,特别是list 和map。

MyTestUtil.java

package utils;

import java.lang.reflect.Field;

import java.text.SimpleDateFormat;

import java.util.Arrays;

import java.util.Collection;

import java.util.Date;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

/**

* 这个类是方便控制台输出object,主要应用java反射机制。 因为考虑到使用性和美观性,没有使用无限递归。

* 而是在toStr方法中加入一个boolean recursion ,是否递归。

* 当然我们也可以将boolean recursion换成int recursion,控制递归次数。

* 其实就我使用经验来看,复杂数据toString,用json工具转化成json输出是一个不错的方式。

//这是我用的方式,boolean recursion是否递归

public static int add(int i,boolean recursion){

sum+=i;

if(recursion)

add(i, false);

return sum;

}

//也可以这样,int recursion表示递归次数

public static int add(int i,int recursion){

sum+=i;

if(recursion>0){

recursion--;

add(i, recursion);

}

return sum;

}

*

*

* @author klguang

*

*/

public class MyTestUtil {

static final String SPLIT_LINE = "=";// 分割线

static final String MY_SIGN = "KLG_print";//默認標記

private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

/**

* 将集合类型toSring方法

* @param object

* @param recursion

* 是否递归

* @return

*/

private static String collectionToStr(Object object, boolean recursion) {

if (object == null)

return "null";

Object[] a = null;

// 将集合类型转换成数组类型

if (isArrayType(object))

a = (Object[]) object;

else

a = ((Collection) object).toArray();

if (isSimpleArr(a) || !recursion)

return Arrays.toString(a);

else

return complexArrToStr(a);

}

/**

* Arrays有toString方法,但是对象内容太多,在一行显示 还有就是没有显示index信息

*/

private static String complexArrToStr(Object[] a) {

if (a == null)

return "null";

int iMax = a.length - 1;

if (iMax == -1)

return "[]";

StringBuilder b = new StringBuilder();

for (int i = 0;; i++) {

String value = objToStr(a[i], false);

b.append("[" + i + "]" + " -> " + value);

if (i == iMax)

return b.toString();

b.append(", \r\n");

}

}

/**

* map类型toString方法

*

* @param map

* @param recursion

* 是否递归

* @return

*/

private static String mapToStr(Map map, boolean recursion) {

if (map == null)

return "null";

if (isSimpleMap(map) || !recursion)

return simpleMapToStr(map);

else

return complexMapToStr(map, true);

}

/**

* map的value是简单类型的,复制Map.toString,我给它加了换行10个换行

*

* @param map

* @return

*/

private static String simpleMapToStr(Map map) {

Iterator> i = map.entrySet().iterator();

if (!i.hasNext())

return "{}";

StringBuilder sb = new StringBuilder();

sb.append('{');

for (int t = 1;; t++) {

Entry e = i.next();

sb.append(e.getKey()).append(" = ").append(e.getValue());

if (!i.hasNext())

return sb.append('}').toString();

sb.append(',').append(' ');

if (t % 10 == 0 && t != 0)

sb.append("\r\n ");

}

}

private static String complexMapToStr(Map map, boolean recursion) {

Iterator> i = map.entrySet().iterator();

if (!i.hasNext())

return "{}";

StringBuilder sb = new StringBuilder();

sb.append("{\r\n");

for (int t = 1;; t++) {

Entry e = i.next();

String key = String.valueOf(e.getKey());

Object value = e.getValue();

sb.append(indent(2," ")).append(key).append(" = ");

if (isSimpleType(value) || !recursion)

sb.append(String.valueOf(value));

else

sb.append(objToStr(value, false));

if (!i.hasNext())

return sb.append("\r\n}").toString();

sb.append(',').append("\r\n");

}

}

/**

*

*

* @param object

* @param recursion

* 是否要递归

* @return

*/

private static String beanToStr(Object object, boolean recursion) {

if (object == null)

return "null";

Class clazz = object.getClass();

StringBuilder sb = new StringBuilder();

//返回源代码中给出的底层类的简称

sb.append(clazz.getSimpleName()).append("[");

Field[] fields = sortFieldByType(clazz.getDeclaredFields());

int iMax = fields.length - 1;

if (iMax == -1)

return sb.append("]").toString();

for (int i = 0;; i++) {

Field field = fields[i];

field.setAccessible(true);// 设置些属性是可以访问的

String name = field.getName();// 取得field的名称

if (name.equals("serialVersionUID"))

continue;

try {

Object value = field.get(object);// 得到此属性的值

if (isSimpleType(value) || !recursion)

sb.append(name + " = " + String.valueOf(value));

else

sb.append("\r\n" + indent(clazz.getSimpleName().length() + 2," ")

+ objToStr(value, false) + "\r\n");

} catch (Exception e) {

e.printStackTrace();

}

if (i == iMax)

return sb.append("]").toString();

sb.append(",");

}

}

private static String indent(int length,String sign) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < length; i++) {

sb.append(sign);

}

return sb.toString();

}

private static boolean isSimpleType(Object obj) {

if (obj == null)

return true;

else {

Class objectClass = obj.getClass();

return isSimpleType(objectClass);

}

}

/**

*

* @param objectClass

* 用obj.getClass()取得

* @return

*/

private static boolean isSimpleType(Class objectClass) {

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 true;

} else {

return false;

}

}

/**

* Method isCollectionType

*

* @param obj

* Object

* @return boolean

*/

private static boolean isCollectionType(Object obj) {

if (obj == null)

return false;

return (obj.getClass().isArray() || (obj instanceof Collection));

}

private static boolean isArrayType(Object obj) {

if (obj == null)

return false;

return (obj.getClass().isArray());

}

private static boolean isMapType(Object obj) {

if (obj == null)

return false;

return (obj instanceof Map);

}

private static boolean isDateType(Object obj){

if(obj==null)

return false;

return (obj instanceof Date);

}

private static boolean isBeanType(Object obj) {

if (isSimpleType(obj) || isCollectionType(obj) || isMapType(obj))

return false;

else

return true;

}

private static boolean isSimpleArr(Object[] a) {

if (a == null || a.length < 1)

return true;

boolean flag = true;

for (Object o : a) {

if (!isSimpleType(o)) {

flag = false;

break;

}

}

return flag;

}

private static boolean isSimpleMap(Map map) {

if (map == null)

return true;

Iterator> i = map.entrySet().iterator();

boolean flag = true;

while (i.hasNext()) {

Entry e = i.next();

if (!isSimpleType(e.getValue())) {

flag = false;

break;

}

}

return flag;

}

/***

* 将简单类型排在前面

* @param fields

* @return

*/

public static Field[] sortFieldByType(Field[] fields) {

for (int i = 0; i < fields.length; i++) {

if (isSimpleType(fields[i].getType()))

continue;// fields[i]是简单类型不管

// fields[i]是复杂类型

// int j = i+1,从fields[i]之后开始比较

for (int j = i + 1; j < fields.length; j++) {

Field fieldTmp = null;

if (isSimpleType(fields[j].getType())) {// 与后面的第一个简单类型交互

fieldTmp = fields[i];

fields[i] = fields[j];

fields[j] = fieldTmp;

break; // 后面的循环,是没有意义de

}

}

}

return fields;

}

/**

* 这个方法是递归方法,并且并多个地方调用,考虑到循环引用和显示格式, boolean recursion取得确保递归可以被终止。

*

* @param object

* @param recursion

* 是否需要更深一层显示

* @return

*/

private static String objToStr(Object object, boolean recursion) {

if (object == null)

return "null";

object.toString();

if(isDateType(object))

return new SimpleDateFormat(DATE_FORMAT).format((Date)object);

else if (isBeanType(object))

return beanToStr(object, recursion);

else if (isCollectionType(object))

return collectionToStr(object, recursion);

else if (isMapType(object))

return mapToStr((Map) object, recursion);

else

return String.valueOf(object);

}

public static String objToStr(Object obj) {

return objToStr(obj, true);

}

private static void print(Object obj,String sign,String content) {

String begin=indent(15, SPLIT_LINE) + " " +obj.getClass().getSimpleName()

+ " >> " + sign + " " + indent(10, SPLIT_LINE);

int length=(begin.length()-sign.length()-5)/2;

String end=indent(length, SPLIT_LINE)+ " " + sign + " " + indent(length, SPLIT_LINE);

System.out.println(begin+"\r\n"+content+"\r\n"+end);

}

public static void print(Object obj){

print(obj,MY_SIGN,objToStr(obj));

}

public static void printWithSign(String sign, Object obj) {

print(obj, sign,objToStr(obj));

}

}

不过呢上面代码太繁琐了,没有考虑多种类型嵌套的问题。

数组类型强转会报ClassCastException 。

平常打日志就用log4j写个工具方法 比上面这个清晰明了多了。

public static void debug(String message,Object o){

int count=0;

if(o==null){

LOGGER.debug(chain(message,": null"));

return;

}

if(o.getClass().isArray()){

for(int i=0,len=Array.getLength(o);i

debug(chain(message,"-[",i,"]"),Array.get(o, i));

}

}else if(o instanceof Map){

Entry,?> e;

for(Iterator> it=((Map,?>)o).entrySet().iterator();it.hasNext();){

e=(Entry,?>) it.next();

debug(chain(message,"-[K:",e.getKey(),"]"),e.getValue());

}

}else if(o instanceof Iterable){

for(Iterator> it=((Iterable>) o).iterator();it.hasNext();){

count++;

debug(chain(message,"-[",count,"]"),it.next());

}

}else{

LOGGER.debug(chain(message,":",o));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值