Как получить поля в объекте с помощью отражения? - PullRequest
63 голосов
/ 07 июня 2010

У меня есть объект (в основном VO) в Java, и я не знаю его тип.
Мне нужно получить значения, которые не являются нулевыми в этом объекте.

Как это можно сделать?

Ответы [ 3 ]

121 голосов
/ 07 июня 2010

Вы можете использовать Class#getDeclaredFields(), чтобы получить все объявленные поля класса. Вы можете использовать Field#get(), чтобы получить значение.

Короче говоря:

Object someObject = getItSomehow();
for (Field field : someObject.getClass().getDeclaredFields()) {
    field.setAccessible(true); // You might want to set modifier to public first.
    Object value = field.get(someObject); 
    if (value != null) {
        System.out.println(field.getName() + "=" + value);
    }
}

Чтобы узнать больше об отражении, посмотрите учебник Sun по этому предмету .


Тем не менее, поля не обязательно все представляют свойства VO. Вы бы предпочли определить публичные методы, начинающиеся с get или is, а затем вызвать их, чтобы получить значения свойств real .

for (Method method : someObject.getClass().getDeclaredMethods()) {
    if (Modifier.isPublic(method.getModifiers())
        && method.getParameterTypes().length == 0
        && method.getReturnType() != void.class
        && (method.getName().startsWith("get") || method.getName().startsWith("is"))
    ) {
        Object value = method.invoke(someObject);
        if (value != null) {
            System.out.println(method.getName() + "=" + value);
        }
    }
}

Тем не менее, в свою очередь, могут быть более изящные способы решения вашей настоящей проблемы. Если вы подробнее расскажете о функциональных требованиях, для которых вы считаете, что это правильное решение, мы можем предложить правильное решение. Есть много многих инструментов, доступных для массажа javabeans.

12 голосов
/ 07 июня 2010

Вот быстрый и грязный метод, который делает то, что вы хотите, в общем виде. Вам нужно будет добавить обработку исключений, и вы, вероятно, захотите кэшировать типы BeanInfo в weakhashmap.

public Map<String, Object> getNonNullProperties(final Object thingy) {
    final Map<String, Object> nonNullProperties = new TreeMap<String, Object>();
    try {
        final BeanInfo beanInfo = Introspector.getBeanInfo(thingy
                .getClass());
        for (final PropertyDescriptor descriptor : beanInfo
                .getPropertyDescriptors()) {
            try {
                final Object propertyValue = descriptor.getReadMethod()
                        .invoke(thingy);
                if (propertyValue != null) {
                    nonNullProperties.put(descriptor.getName(),
                            propertyValue);
                }
            } catch (final IllegalArgumentException e) {
                // handle this please
            } catch (final IllegalAccessException e) {
                // and this also
            } catch (final InvocationTargetException e) {
                // and this, too
            }
        }
    } catch (final IntrospectionException e) {
        // do something sensible here
    }
    return nonNullProperties;
}

См. Эти ссылки:

4 голосов
/ 07 июня 2010

У меня есть объект (в основном VO) в Я и я не знаю его тип. Мне нужно получить значения, которые не являются нулевыми в этом объекте.

Может быть, вам не нужно для этого размышлять - вот простой ОО дизайн , который может решить вашу проблему:

  1. Добавьте интерфейс Validation, который предоставляет метод validate, который проверяет поля и возвращает все, что подходит.
  2. Реализовать интерфейс и метод для всех ВО.
  3. Когда вы получаете VO, даже если его тип конкретный неизвестен, вы можете ввести его на Validation и проверить это легко.

Полагаю, что для отображения сообщения об ошибке универсальным образом необходимо поле, равное нулю, поэтому этого должно быть достаточно. Дайте мне знать, если это не сработает для вас по какой-то причине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...