我必须在日志文件中打印对象值。我用过:
ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE, true, true);
,但它也打印了我不想包括的空值,例如:
pojo@117d9a3 [id = 1, name = null ,description = Manchester United,key = app-key,secretkey,secretkey = alex]
如何抑制被包括在内的空值?
一个没有子类别的简单解决方案是覆盖接受方法:
public String toStringWithAttributes() {
Object myself = this;
ReflectionToStringBuilder builder = new ReflectionToStringBuilder(
this, ToStringStyle.SHORT_PREFIX_STYLE) {
@Override
protected boolean accept(Field field) {
try {
return super.accept(field) && field.get(myself) != null;
} catch (IllegalAccessException e) {
return super.accept(field);
}
}
};
return builder.toString();
}
这具有额外的好处,您可以使用所需的任何ToStringStyle
,而格式化是完美的。
您必须提供自己的ToStringStyle实现。这样的东西(未经测试!):
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.ToStringStyle;
public final class NotNullToStringStyle extends ToStringStyle {
public static final ToStringStyle NOT_NULL_STYLE = new NotNullToStringStyle();
private static final long serialVersionUID = 1L;
/**
* <p>Constructor.</p>
*
* <p>Use the static constant rather than instantiating.</p>
*/
NotNullToStringStyle() {
super();
this.setContentStart("[");
this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " ");
this.setFieldSeparatorAtStart(true);
this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
}
/**
* <p>Ensure <code>Singleton</code> after serialization.</p>
*
* @return the singleton
*/
private Object readResolve() {
return NOT_NULL_STYLE;
}
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
if (value != null) {
appendFieldStart(buffer, fieldName);
appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
appendFieldEnd(buffer, fieldName);
}
}
}
大多数代码都是从MultiLineToStringStyle
复制的,因为它是private
和final
,因此我们无法将其扩展。真实的事情发生在append
方法中。这是最初的参考:
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);
}
从apache commons-lang3:
中存在框实现。reflectionToStringBuilder.ToString(new Pojo(),tostringstyle.default_style,true,true,false, true ,null)
输出按要求:
general.Pojo@3532ec19[description=Manchester,id=1]
使用:
公共静态字符串tostring(最终T对象,最终的Tostringstyle样式,最终的布尔输出传输,最终的布尔量输出史塔式,最终布尔值排除,最终类;超级t&gt;Reflectoplass)
@christian sporer的答案(抬起他),但被修改为可重复使用的util方法:
public class ToStringUtil {
public static String toStringWithAttributes(Object ofInterest, ToStringStyle style) {
ReflectionToStringBuilder builder = new ReflectionToStringBuilder(ofInterest, style) {
@Override
protected boolean accept(Field field) {
try { return super.accept(field) && field.get(ofInterest) != null; }
catch (IllegalAccessException e) { return super.accept(field); }
}
};
return builder.toString();
}
}
自3.6起,有一个内置的方法
ReflectionToStringBuilder.toString(this, ToStringStyle.DEFAULT_STYLE,false,false,true,null);
方法签名是:
ReflectionToStringBuilder.toString(
Object object,
ToStringStyle style,
boolean outputTransients,
boolean outputStatics,
boolean excludeNullValues,
Class<? super Object> reflectUpToClass)
有一种方法可以用自己的文本在此对象上创建新的toStringStyle对象setNullText(String nullText)
,然后将此ToStringStyle对象传递到ReflectionToStringBuilder
类的构造函数中。