web-dev-qa-db-fra.com

Comment obtenir les champs dans un objet via la réflexion?

J'ai un objet (essentiellement un VO) dans Java et je ne connais pas son type.
Je dois obtenir des valeurs qui ne sont pas nulles dans cet objet.

Comment cela peut-il être fait?

65
Swapna

Vous pouvez utiliser Class#getDeclaredFields() pour obtenir tous les champs déclarés de la classe. Vous pouvez utiliser Field#get() pour obtenir la valeur.

En bref:

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

Pour en savoir plus sur la réflexion, consultez le tutoriel de Sun sur le sujet .


Cela dit, les champs ne représentent pas nécessairement tous des propriétés d'un VO. Vous préféreriez plutôt déterminer les méthodes publiques commençant par get ou is, puis l'invoquer pour récupérer les valeurs de la propriété 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);
        }
    }
}

Cela dit, il existe peut-être des moyens plus élégants de résoudre votre problème actuel. Si vous développez un peu plus les exigences fonctionnelles pour lesquelles vous pensez que c'est la bonne solution, nous pourrons peut-être vous proposer la bonne solution. Il existe de nombreux outils nombreux pour masser les javabéens.

123
BalusC

Voici une méthode rapide et sale qui fait ce que vous voulez de manière générique. Vous aurez besoin d'ajouter la gestion des exceptions et vous voudrez probablement mettre en cache les types BeanInfo dans un faible faiblesse.

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

Voir ces références:

12

J'ai un objet (essentiellement un VO) dans Java) et je ne connais pas son type. J'ai besoin d'obtenir des valeurs qui ne sont pas nulles dans cet objet.

Peut-être que vous n'avez pas nécessairement besoin de réflexion pour cela - voici un en clair OO conception) qui pourrait résoudre votre problème:

  1. Ajoutez une interface Validation qui expose une méthode validate qui vérifie les champs et renvoie ce qui est approprié.
  2. Implémentez l'interface et la méthode pour tous les VO.
  3. Lorsque vous obtenez un VO, même si son type concret est inconnu, vous pouvez le transtyper en Validation et le vérifier facilement.

Je suppose que vous avez besoin des champs nuls pour afficher un message d'erreur de manière générique, cela devrait donc suffire. Faites-moi savoir si cela ne fonctionne pas pour vous pour une raison quelconque.

4
ewernli