Подтвердить что ты не робот

Как получить поля в объекте через отражение?

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

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

4b9b3361

Ответ 1

Вы можете использовать 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, а затем вызывать его для захвата значений реальных свойств.

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);
        }
    }
}

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

Ответ 2

Вот быстрый и грязный метод, который делает то, что вы хотите в общем виде. Вам нужно будет добавить обработку исключений, и вам, вероятно, захочется кэшировать типы 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;
}

См. следующие ссылки:

Ответ 3

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

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

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

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