Пишу универсальный метод toString для класса с помощью рефлексии. Работает, но есть один трабл...

0
13 июл 2015 06:59
Здравствуйте.
Я - тестировщик. Пишу тесты и мне нужно знать состояние объектов. Я решил написать один универсальный метод для отладки.
Подумал что рефлексия для этого подойдет как нельзя лучше.

Вот класс

public class Test {

  public String getC() {
    return c;
  }

  public String getB() {
    return b;
  }

  public Object[] getC2() {
    return c2;
  }
  private String b ="aaa";
  private  String c = "ds";
  private Hosts[] c2 = new Hosts[ ] {new Hosts() } ; ;



  void pri  (){

    List <String> mList = new LinkedList<String>();


    for (Method met : this.getClass().getMethods()) {
      if ( (met.getName().startsWith("get"))&& (!met.getName().equals("getClass")))
      {
        try {
          Object a =   met.invoke(this);
          mList.add(met.getName().substring(3) + "\t\"" + a + "\" \n");
        } catch (IllegalAccessException | InvocationTargetException e) {
          e.printStackTrace();
        }
      }

    }
    Collections.sort(mList);
    mList.add(0,"Содержание полей объекта " + this.getClass().getSimpleName() + ":\n");
    System.out.println(mList.toString());

  }


запуск такой:
  new Test().pri();  //Потом переименую

вывод такой:

[Содержание полей объекта Test:
, B "aaa"
, C "ds"
, C2 "[Lru.hh.tests.functional.suites.hhapi.utils.Hosts;@48533e64"
]


Все хорошо с примитивными типами а вот если методы возвращают массив или другой объект какого то класса то в выводе черте-чо:
@48533e64

1)Есть ли способ написать такой код который бы понимал что если это объект а не примитив то вызвать у него toString?
2)Еще хочу получить объект, проверить есть ли у него поле length (или аналогичное) чтобы итерировать его, притом класс заранее не известен
(не хочу писать свичи и кастовать). реально?

Ответов: 3

2
13 июл 2015 08:55
Я бы на вашем месте заиспользовал gson или jackson и не мучился с написанием собственного кода. Либо lombok
2
13 июл 2015 08:24
Quote:
Я читал что использовать instanceof плохо

Если вы используете рефлексию, то instanceof вам уже не навредит. :)

Можете вместо него getClass().isAssignableFrom() использовать - те же яйца, только в профиль.

В общем он не плох сам по себе - просто иногда он свидетельствует о том что автор кода плохо понимал ООП и понаделал костылей. Но в вашем случае речь об абстракциях и архитектуре не идёт.
2
13 июл 2015 07:25
Если пишите сами, то кастовать и перебирать типы придётся. Но их немного, всего пяток:
instanceof Number - Byte, Double, Integer, практически все типы чисел
instanceof CharSequence - прежде всего это строка, но есть и другие варианты
instanceof Iterable - включает все коллекции
getClass().isArray() - массивы

В итоге для "примитивов" делаете toString, для остального (коллекции и пользовательские типы) вызываетесь рекурсивно.
Модераторы: Нет
Сейчас эту тему просматривают: Нет