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));
}
}
Java对象的打印_java反射原理制作对象打印工具相关推荐
- java中对象字节数_JAVA中求解对象所占字节大小
该类为cache4j缓存框架中的工具类方法,该方法实现了两个接口 接口1:计算对象在内存中所占字节数 接口2:复制对象,实现深度克隆效果,实现原理为先序列化对象,然后在反序列化对象:返回一个新的对象, ...
- java excel 插入文件_Java 添加OLE对象到Excel文档
本文介绍通过Java程序添加OLE对象到Excel文档.OLE分为两种形式,一种通过嵌入(Embed),方式,一种通过链接(Link)方式.前者是将对象嵌入到文档中,外部对该对象的更改不影响嵌入操作时 ...
- java 参数传递为空_java 参数传递 空对象 null
前两天,写程序时候,想传递一个数组名给一个函数,然后给数组new一下,并初始化数据,这样就使用非return,获得了一个初始化过对象,但是运行程序报"NullPointerException ...
- java类对象实验问题_Java类与对象实验答案
Java类与对象实验答案Tag内容描述: 1.Java实验报告 计科.信工版2013-2014-2 实验报告 一.实验项目:类与对象 二.实验目的: 1. 学会使用类来封装对象的属性和功能 2. 掌握 ...
- java 父类转子类_Java多态,对象转型,和简单工厂模式。希望对您有帮助!
各位读者老爷们大家好鸭~图图又来了,今天我们要说一下"多态". 怎么理解这两个字呢?可以理解为同一个引用对象的不同表现形态,即将父类的引用指向子类的对象.这是比较官方的书面解释,大 ...
- java类笔试题_Java类和对象笔试题
案例描述:领养宠物并打印宠物信息 创建宠物狗狗类(Dog),狗狗类的属性: 昵称(name).健康值(health).亲密度(love).品种(strain): 狗狗类的方法(print):打印自己的 ...
- Java类和对象基础题_java类和对象基础题2
创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它. import java.util.*;public classSanjiao {private doublea,b,c;privat ...
- java动态添加属性_java – 动态添加对象的属性
你好: 在我们的应用程序中,我们从数据库中检索了一些数据,例如,表格中包含以下字符:id,name,age,address,email. 然后我们将根据客户获得一些这些属性. 如果客户端需要id,na ...
- java 管理对象是什么_Java工程师(16)对象的管理
包 包的创建规则 包可以有层次,在创建包时可以一次性创建多级包,上下级之间用"."分割,如下图所示. 访问修饰符 简介 访问修饰符包括:private.protected.publ ...
最新文章
- PhiSpy:在细菌基因组中识别噬菌体
- oracle insert parallel,insert /*parallel */ 到不同用户,并行起不来的问题
- 洛谷 P2867 [USACO06NOV]大广场Big Square
- 一分钟学会看k线图_看K线图:阴跌如钝刀
- 面向对象之迪米特法则
- Groovy全攻略--嵌入篇
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器
- 使用 ssmtp 於 shell 透過 Gmail 寄信
- W3CSchool离线手册文档
- java pdf 水印 加密_Java生成PDF 加密 水印
- medsem-中介效应:基于结构方程模型SEM的中介效应分析
- 尜尜送的诗,以及我回的句
- UI面试官的哪些问题让你感觉很高明?
- 2022年4月编程语言排行
- Python/虚数or复数的表示
- 37、在OAK摄像头上部署tensorflow deeplabv3+进行实例分割
- Foundations of Machine Learning 2nd——第二章 PAC学习框架 后记
- ubuntu下qt模拟键盘按键按下_基于QT的跨平台虚拟键盘设计与实现
- 树莓派 EC20 mini pcie 开机自动拨号
- 中国历史上三大盛世的理性审视
热门文章
- 博通Broadcom SDK源码学习与开发11——Cable Modem DHCP管理
- 基于jsp+ssm的爱康医院专家预约管理系统
- 高等数学:第四章 不定积分(1)不定积分的概念与性质 换元积分法
- 合宙 ESP32C3 使用micropython 驱动配套0.96寸 TFT ST7735 屏幕显示色块和文字
- PX4 Autopilot源码分析 - 总体架构
- 面试官-你真的懂computed原理?(源码解读)
- 范畴(Category)
- 艾永亮:中国企业如何跳出竞争红海?超级产品战略引发新思考
- 计算机编程语言发展史
- ​2022企业级BI平台白皮书(附下载)