超级强悍的java对象属性查看工具

在做一个hadoop的editlog查看工具,由于editlog都是用dataoutputStream输出的,在载入这类文件需要完全相反的方向DatainputStream先转换成对应的类,这个非常麻烦。特别是有部分类的成员是private的,也没有提供get方法,如何方便打印这些信息。想到只有用终极武器反射来完成这样的使命,以下就是我写的可以完全遍历对象树并将对象用json格式打印处理的code。

public class ObjectViewer {
	public ObjectViewer() {
	}

	@SuppressWarnings("rawtypes")
	private void fetchAllFields(Class c, List<Field> fields) {
		assert fields != null;
		if (c == Object.class || c.isPrimitive() || c.isArray() || c == String.class) {
			return;
		} else {
			fetchAllFields(c.getSuperclass(), fields);
			for (Field field : c.getDeclaredFields()) {
				field.setAccessible(true);
				fields.add(field);
			}
		}
	}

	private StringBuilder buildPrimitiveField(Field field, Object instance,
			StringBuilder builder) throws IllegalArgumentException,
			IllegalAccessException {
		assert field.getType().isPrimitive();
		Object v = field.get(instance);
		if(v == null){
			return builder;
		}
		return builder.append(field.getName() + ":" + v);
	}

	private StringBuilder buildStringField(Field field, Object instance,
			StringBuilder builder) throws IllegalArgumentException,
			IllegalAccessException {
		assert field.getType() == String.class;
		Object v = field.get(instance);
		if(v == null){
			return builder;
		}
		return builder.append(field.getName() + ":\"" + v + "\"");
	}

	private StringBuilder buildArrayField(Field field, Object instance,
			StringBuilder builder) throws Exception{
		assert field.getType().isArray();
		Object v = field.get(instance);
		if(v == null){
			return builder;
		}
		builder.append(field.getName());
		builder.append(":[");
		boolean isFirst = true;
		for (int i = 0; i < Array.getLength(v); i++) {
			if(!isFirst){
				builder.append(',');
			}else{
				isFirst = false;
			}
			buildObject(Array.get(v, i),builder);
		}
		builder.append(']');
		return builder;
	}

	private StringBuilder buildClassField(Field field, Object instance,
			StringBuilder builder) throws Exception {
		assert !(field.getType().isPrimitive()
				|| field.getType() == String.class || field.getType().isArray());
		Object v = field.get(instance);
		if(v == null){
			return builder;
		}
		buildObject(v,builder);
		return builder;
	}
	@SuppressWarnings("rawtypes")
	public StringBuilder buildObject(Object obj, StringBuilder builder){
		try{
			Class objClazz = obj.getClass();
			if(objClazz.isPrimitive() || objClazz == String.class || obj instanceof Number){
				return builder.append("" + obj);
			}
			List<Field> allFields = new ArrayList<Field>();
			fetchAllFields(obj.getClass(), allFields);
			builder.append('{');
			boolean isFirst = true;
			for (Field field : allFields) {
				if(!isFirst){
					builder.append(',');
				}else{
					isFirst = false;
				}
				Class type = field.getType();
				if (type.isPrimitive()) {
					buildPrimitiveField(field, obj, builder);
				} else if (type == String.class) {
					buildStringField(field, obj, builder);
				} else if (type.isArray()) {
					buildArrayField(field, obj, builder);
				} else {
					buildClassField(field, obj, builder);
				}
			}
			builder.append('}');
			return builder;
		}catch (Exception e) {
			e.printStackTrace();
			return builder;
		}
		
	}

	public static void main(String[] args) throws Exception{
//		System.out.println(Integer.class.isPrimitive());
		ObjectViewer objviever = new ObjectViewer();
		System.out.println(objviever.buildObject(objviever,new StringBuilder()).toString());
//		System.out.println(objviever.buildObject(new ArrayObj()));
	}

}

 

使用方法非常简单,扔个对象进去,不管他有多复杂的结构,都会把对象的所有属性打印出来。

你可能感兴趣的:(java,C++,c,hadoop,C#)