经过一段时间查看linux上日志,发现日志里面大量打印JAVA对象是null的情况,遇到到业务问题时,常常需要通过对象的当时快照去定位问题,
这时需要消耗很多时间去查找对应的关键对象属性字段数据是否准确,非常的繁琐,影响效率。
eg:
1、根据问题的情况分析,确定是对ToString()重写造成的。
@Override public String toString() { return ToStringBuilder.reflectionToString(this); }
2、根据1中,调用了Apache的ToStringBuilder做答应对象,分析Apache的整个对象中,打印对象的方式为:
public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics, Class reflectUpToClass) { return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics) .toString(); } public String toString() { if (this.getObject() == null) { return this.getStyle().getNullText(); } Class clazz = this.getObject().getClass(); this.appendFieldsIn(clazz); while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) { clazz = clazz.getSuperclass(); this.appendFieldsIn(clazz); } return super.toString(); }
3、使用ToStringStyle可以改变ToStringBuilder打印对象的样式,ToStringStyle是一个抽象的类,可以重写定制。
在ToStringStyle有一个append()方法,重写即可:
eg:ToStringStyle的append()
public abstract class ToStringStyle implements Serializable { ... public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) { appendFieldStart(buffer, fieldName); if (value == null) { appendNullText(buffer, fieldName); } else { appendInternal(buffer, fieldName, value, isFullDetail(fullDetail)); } appendFieldEnd(buffer, fieldName); } }
在ToStringBuilder中,还有个可以传入自己Style的方式,eg:public static String reflectionToString(Object object, ToStringStyle style);
根据二中的分析,我们可以重写ToStringStyle,在调用return ToStringBuilder.reflectionToString(this, style)的时候,传入自己定制的ToStringStyle即可。
@Override public String toString() { return ToStringBuilder.reflectionToString(this, new NoNullStyle()); }
根据一中问题的描述,我们对null的字段不做打印出来,但是对""的还是要打印的,所以需要重写Style中的追加字符串方法即可:
源码如下:
import org.apache.commons.lang.builder.ToStringStyle; import java.io.Serializable; /** * 功能描述:重写ToStringStyle,不打印出对象的空属性字段 * <p/> * null 不打印 * “” 打印 * * @author : Zhenbin.Li * Date: 15/8/5 Time: 11:21 */ public class NoNullStyle extends ToStringStyle implements Serializable { private static final long serialVersionUID = 2347542971151578670L; @Override public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) { if (value != null) { super.append(buffer, fieldName, value, fullDetail); } } }
使用方式,在对象中,重写toString()方法:
eg:
@Override public String toString() { return ToStringBuilder.reflectionToString(this, new NoNullStyle()); }