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";// J 
  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
"); } } /** * map toString * * @param map * @param recursion * * @return */ private static String mapToStr(Map<String, Object> 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<Entry<String, Object>> i = map.entrySet().iterator(); if (!i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append('{'); for (int t = 1;; t++) { Entry<String, Object> 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
"); } } private static String complexMapToStr(Map map, boolean recursion) { Iterator<Entry<String, Object>> i = map.entrySet().iterator(); if (!i.hasNext()) return "{}"; StringBuilder sb = new StringBuilder(); sb.append("{\r
"); for (int t = 1;; t++) { Entry<String, Object> 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
}").toString(); sb.append(',').append("\r
"); } } /** * * * @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
" + indent(clazz.getSimpleName().length() + 2," ") + objToStr(value, false) + "\r
"); } 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<Entry<String, Object>> i = map.entrySet().iterator(); boolean flag = true; while (i.hasNext()) { Entry<String, Object> 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
"+content+"\r
"+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)); } }
でも、上のコードは煩雑すぎて、いろいろな種類の入れ子の問題を考えていません。
配列タイプの強い移籍報告Class CastException。
普段は日記を書く時に、ロゴ4 jを使ってツールを書く方が上の方よりずっとはっきりしています。

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<len;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));
}
}