ToStringBuilder の reflectionToString
たとえばこんなコード
List<Hoge> l = Arrays.asList(new Hoge("S1", 1), new Hoge("S2", 2)); Bar bar = new Bar(100, l); System.out.println(ToStringBuilder.reflectionToString(bar));
以下のような出力が得られる。
etc9.Bar@1a457b6[id=100,list=[etc9.Hoge@b0f13d, etc9.Hoge@ae000d]]
だけどlistの中身がみたい
listの中のオブジェクトなどを再帰的に表示したくないでしょうか?ToStringStyle を拡張することで、reflectionToString の出力形式を簡単に変更できます。指定パッケージのオブジェクトは再帰的に中身を表示するようにしてみます。
public class RecursiveToSrtingStyle extends ToStringStyle { private List<String> recursivePackags; private int recursiveLimit = 10; public RecursiveToSrtingStyle(String... pkgs) { super(); recursivePackags = Arrays.asList(pkgs); //this.setUseShortClassName(true); this.setUseIdentityHashCode(false); } @Override protected void appendDetail(StringBuffer buffer, String fieldName, Object value) { for(String packaz : recursivePackags) { if (value.getClass().getCanonicalName().startsWith(packaz)) { buffer.append(ToStringBuilder.reflectionToString(value, this)); return; } } buffer.append(value); } @Override protected void appendDetail(StringBuffer buffer, String fieldName, Map map) { buffer.append(getArrayStart()); int count = 0; for(Entry<?, ?> entry : ((Map<? ,?>)map).entrySet()) { appendDetail(buffer, fieldName, entry.getKey()); buffer.append(getFieldNameValueSeparator()); appendDetail(buffer, fieldName, entry.getValue()); appendFieldSeparator(buffer); if((count++) > recursiveLimit) { buffer.append("..."); break; } } removeLastFieldSeparator(buffer); buffer.append(getArrayEnd()); } @Override protected void appendDetail(StringBuffer buffer, String fieldName, Collection coll) { appendContentStart(buffer); int count = 0; for(Object o : coll){ appendDetail(buffer, fieldName, o); appendFieldSeparator(buffer); if((count++) > recursiveLimit) { buffer.append("..."); break; } } removeLastFieldSeparator(buffer); appendContentEnd(buffer); } }
オブジェクト用、Map用、Collection用の処理をオーバーライドします。
実行
List<Hoge> l = Arrays.asList(new Hoge("S1", 1), new Hoge("S2", 2)); Bar bar = new Bar(100, l); System.out.println(ToStringBuilder.reflectionToString(bar, new RecursiveToSrtingStyle("etc9")));//etc9パッケージ以下を再帰出力
以下のような出力が得られました。
etc9.Bar[id=100,list=[etc9.Hoge[foo=S1,var=1],etc9.Hoge[foo=S2,var=2]]]
ばんざい。
おまけに ToStringStyle で定義されている出力結果を。
DEFAULT_STYLE
ToStringBuilder.reflectionToString(bar,ToStringStyle.DEFAULT_STYLE); ToStringBuilder.reflectionToString(foo,ToStringStyle.DEFAULT_STYLE);
etc9.Bar@7a78d3[id=100,list=[bar, hoge]] etc9.Foo@ae000d[id=10000,name=Fooo,bar=etc9.Bar@7a78d3,map={Foo=val}]
MULTI_LINE_STYLE
ToStringBuilder.reflectionToString(bar,ToStringStyle.MULTI_LINE_STYLE); ToStringBuilder.reflectionToString(foo,ToStringStyle.MULTI_LINE_STYLE);
etc9.Bar@7a78d3[ id=100 list=[bar, hoge] ] etc9.Foo@ae000d[ id=10000 name=Fooo bar=etc9.Bar@7a78d3 map={Foo=val} ]
NO_FIELD_NAMES_STYLE
ToStringBuilder.reflectionToString(bar,ToStringStyle.NO_FIELD_NAMES_STYLE); ToStringBuilder.reflectionToString(foo,ToStringStyle.NO_FIELD_NAMES_STYLE);
etc9.Bar@7a78d3[100,[bar, hoge]] etc9.Foo@ae000d[10000,Fooo,etc9.Bar@7a78d3,{Foo=val}]
SHORT_PREFIX_STYLE
ToStringBuilder.reflectionToString(bar,ToStringStyle.SHORT_PREFIX_STYLE); ToStringBuilder.reflectionToString(foo,ToStringStyle.SHORT_PREFIX_STYLE);
Bar[id=100,list=[bar, hoge]] Foo[id=10000,name=Fooo,bar=etc9.Bar@7a78d3,map={Foo=val}]
SIMPLE_STYLE
ToStringBuilder.reflectionToString(bar,ToStringStyle.SIMPLE_STYLE); ToStringBuilder.reflectionToString(foo,ToStringStyle.SIMPLE_STYLE);
100,[bar, hoge] 10000,Fooo,etc9.Bar@7a78d3,{Foo=val}