reflect:打印对象属性内容---调试工具

本文介绍了一个强大的Java工具,通过反射机制打印任意对象的详细内容,极大简化了程序调试工作。该工具提供了多种方法来处理不同类型的对象,包括集合、复杂类型和基本类型,帮助开发者更高效地理解和定位代码中的问题。
一个很好用的打印对象内容的工具:
它的typeToString(String scope, Object obj)方法,采用java的reflect机制,可以打印出任何对象的内容.
这对调试程序非常有用.
使用方法:
如果你有一个对象(比如testClassObject),想打印它的内容,可用如下方法:
System.out.println(TypeUtil.typeToString("yourClassObjectName",testClassObject));
以下为LogClassPrintUnit源程序:


</pre><pre name="code" class="java">
</pre><pre name="code" class="java">package com.pmp.util;

import java.util.*;
import java.lang.reflect.*;

/**
 * @category 工具类,打印对象的工具
 * @author xuanweijian
 */

public class LogClassPrintUnit {

	/**
	 * 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 + ": <already visited>/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.
	 * 
	 * @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");
		}
	}
}

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.shardingsphere.infra.config.RuleConfiguration]: Factory method 'readWriteSplittingRuleConfiguration' threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:641) ... 154 common frames omitted Caused by: java.lang.NullPointerException: null at org.apache.shardingsphere.readwritesplitting.yaml.swapper.ReadwriteSplittingRuleAlgorithmProviderConfigurationYamlSwapper.swapToObject(ReadwriteSplittingRuleAlgorithmProviderConfigurationYamlSwapper.java:63) at org.apache.shardingsphere.readwritesplitting.spring.boot.ReadwriteSplittingRuleSpringbootConfiguration.readWriteSplittingRuleConfiguration(ReadwriteSplittingRuleSpringbootConfiguration.java:63) at org.apache.shardingsphere.readwritesplitting.spring.boot.ReadwriteSplittingRuleSpringbootConfiguration$$EnhancerBySpringCGLIB$$a1e7a2c7.CGLIB$readWriteSplittingRuleConfiguration$0(<generated>) at org.apache.shardingsphere.readwritesplitting.spring.boot.ReadwriteSplittingRuleSpringbootConfiguration$$EnhancerBySpringCGLIB$$a1e7a2c7$$FastClassBySpringCGLIB$$eb1d5047.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) at org.apache.shardingsphere.readwritesplitting.spring.boot.ReadwriteSplittingRuleSpringbootConfiguration$$EnhancerBySpringCGLIB$$a1e7a2c7.readWriteSplittingRuleConfiguration(<generated>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ... 155 common frames omitted 配置信息如下: rules: readwrite-splitting: data-source: rw_ds: type: Static loadBlancerName: round-robin props: write-data-source-name: ds_master read-data-source-names: - ds_slave
08-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值