クラスをよしなにデバッグ出力
いつもコメントいただいているmoto0215さんのクラスをよしなにデバッグ出力したいなに反応してみる。
一般的なやりかたは、クラスのtoStringメソッドを実装するというやり方でしょう。
■Main.java
package test; public class Main { public static void main(String[] args) { Test t = new Test(); t.setNumber(123); t.setStr("abc"); System.out.println(t); } }
■Test.java
package test; public class Test { private int number; private String str; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } public String toString() { return "number = " + number + " str = " + str; } }
■実行結果
number = 123 str = abc
というわけなのですが、これだと全クラス自分でtoStringを実装しなければならないので、結構面倒。
で、汎用的に出来そうなのは、commons-beanutilsだと思い、適当に調べてみるとありました。BeanUtils#describeというメソッドです。
■Main_2.java
package test; import org.apache.commons.beanutils.BeanUtils; public class Main_2 { public static void main(String[] args) throws Exception { Test t = new Test(); t.setNumber(123); t.setStr("abc"); System.out.println(BeanUtils.describe(t)); } }
■実行結果
{class=class test.Test, str=abc, number=123}
AbstractMap#toStringがあるので、いい感じに出ますね。
ついでに入れ子にしたらどうなるか。
■Parent.java
package test; public class Parent { private int number; private Test test; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public Test getTest() { return test; } public void setTest(Test test) { this.test = test; } }
■Main_3.java
package test; import org.apache.commons.beanutils.BeanUtils; public class Main_3 { public static void main(String[] args) throws Exception { Test t = new Test(); t.setNumber(123); t.setStr("abc"); Parent p = new Parent(); p.setNumber(234); p.setTest(t); System.out.println(BeanUtils.describe(p)); } }
■実行結果
{class=class test.Parent, test=number = 123 str = abc, number=234}
というわけで、testフィールドも展開されて表示されます。結構実用的ですね。
ところが、内部クラスに対してやってみると、エラーになってしまいます。なんででしょうね?
■Main_1.java
package test; import org.apache.commons.beanutils.BeanUtils; public class Main_1 { public static void main(String[] args) throws Exception { Test t = new Test(); t.setNumber(123); t.setStr("abc"); System.out.println(BeanUtils.describe(t)); } static class Test { private int number; private String str; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } } }
■実行結果
Exception in thread "main" java.lang.NoSuchMethodException: Property 'number' has no getter method at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1127) at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:686) at org.apache.commons.beanutils.BeanUtilsBean.getNestedProperty(BeanUtilsBean.java:698) at org.apache.commons.beanutils.BeanUtilsBean.getProperty(BeanUtilsBean.java:723) at org.apache.commons.beanutils.BeanUtilsBean.describe(BeanUtilsBean.java:504) at org.apache.commons.beanutils.BeanUtils.describe(BeanUtils.java:145) at test.Main_1.<init>(Main_1.java:15) at test.Main_1.main(Main_1.java:7)