超级剽悍的java对象属性查看工具
超级强悍的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())); } }
使用方法非常简单,扔个对象进去,不管他有多复杂的结构,都会把对象的所有属性打印出来。