悪あがきプログラマー

悪あがきを続けていきたい技術と書評なブログです。トレタでiOSエンジニアやってます。

toString()をリフレクションで書きたい。その2

toString()をリフレクションで書きたい。 - 悪あがきプログラマー
昨日は、フィールドのtoString()をリフレクションで書いてみました。


今日はフィールドが配列のケースを考えてみます。

まず、配列のフィールドを増やしてみました。

public class TestBean {
	private String key;
	private String name;
	private String sex;
	private String age;
	private String[] favorite;

テストクラス
値の初期化

	public static void main(String[] args) {
		TestBean bean = new TestBean();
		bean.setKey("aaa");
		bean.setName("bbb");
		bean.setSex("ccc");
		bean.setAge("ddd");
		bean.setFavorite(new String[] { "xxx", "yyy", "zzz" });

		System.out.println(bean.toString());
	}

とりあえず、実行してみます。

key=aaa, name=bbb, sex=ccc, age=ddd, favorite=[Ljava.lang.String;@38503429, 

あたりまえですが、オブジェクトがまんま出てきました。


ちょっと改造してみた。

@Override
public String toString() {
	StringBuilder sb = new StringBuilder();
	Field[] fields = this.getClass().getDeclaredFields();
	for (Field field : fields) {
		String fieldValue = null;
		try {
			if (field.get(this).getClass().isArray()) {
				fieldValue = toStringArray(field);
			} else {
				fieldValue = field.get(this).toString();
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		sb.append(field.getName() + "=" + fieldValue + ", ");
	}

	return sb.toString();
}

private String toStringArray(Field field) throws IlegalArgumentException,
		IllegalAccessException {
	StringBuilder sb = new StringBuilder();
	Object[] objects = (Object[]) field.get(this);
	sb.append("[");
	for (Object object : objects) {
		sb.append(object + ", ");
	}
	sb.append("]");
	return sb.toString();
}

Class#isArray()を使用して、配列かどうかを確認。
その後、中身を取り出してる。

実行結果

key=aaa, name=bbb, sex=ccc, age=ddd, favorite=[xxx, yyy, zzz, ], 

うん、それっぽく取れてる。


今回はStringの配列だったけど、その他の配列でもうまくいくんだろうか?


試してみる。

Bean

public class TestBean {
	private String key;
	private String name;
	private String sex;
	private String age;
	private String[] favorite;
	private int[] intTest;
	private boolean[] booleanTest;

テストクラス

	public static void main(String[] args) {
		TestBean bean = new TestBean();
		bean.setKey("aaa");
		bean.setName("bbb");
		bean.setSex("ccc");
		bean.setAge("ddd");
		bean.setFavorite(new String[] { "xxx", "yyy", "zzz" });
		bean.setIntTest(new int[] { 1, 2, 3 });
		bean.setBooleanTest(new boolean[] { true, false, true });

		System.out.println(bean.toString());
	}

実行

Exception in thread "main" java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
	at TestBean.toStringArray(TestBean.java:92)
	at TestBean.toString(TestBean.java:76)
	at Test.main(Test.java:16)

エラー

Object[] objects = (Object[]) field.get(this);

で、キャストに失敗。
プリミティブの配列だからなぁ。
これをハンドリングしなきゃダメか><

というところで、時間切れ。
先は長いのう。