web-dev-qa-db-fra.com

Valeur de champ d'obtention générique de réflexion

J'essaie de recevoir une valeur de champ par réflexion. Le problème est que je ne connais pas le type de champs et que je dois le décider tout en obtenant la valeur.

Ce code résulte avec cette exception:

Impossible de définir le champ Java.lang.String avec le nom de champ .... fieldName sur Java.lang.String

Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);

Class<?> targetType = field.getType();
Object objectValue = targetType.newInstance();

Object value = field.get(objectValue);

J'ai essayé de lancer, mais j'ai des erreurs de compilation:

field.get((targetType)objectValue)

ou

targetType objectValue = targetType.newInstance();

Comment puis-je faire ceci?

119
Ido Barash

Comme répondu précédemment, vous devriez utiliser:

Object value = field.get(objectInstance);

Une autre façon, parfois préférable, consiste à appeler le getter de manière dynamique. exemple de code:

public static Object runGetter(Field field, BaseValidationObject o)
{
    // MZ: Find the correct method
    for (Method method : o.getMethods())
    {
        if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
        {
            if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
            {
                // MZ: Method found, run it
                try
                {
                    return method.invoke(o);
                }
                catch (IllegalAccessException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }
                catch (InvocationTargetException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }

            }
        }
    }


    return null;
}

Sachez également que lorsque votre classe hérite d'une autre classe, vous devez déterminer le champ de manière récursive. par exemple, chercher tous les champs d'une classe donnée;

    for (Class<?> c = someClass; c != null; c = c.getSuperclass())
    {
        Field[] fields = c.getDeclaredFields();
        for (Field classField : fields)
        {
            result.add(classField);
        }
    }
127
Marius

Vous devriez passer une méthode objet à obtenir du champ, donc

  Field field = object.getClass().getDeclaredField(fieldName);    
  field.setAccessible(true);
  Object value = field.get(object);
106
Dmitry Spikhalskiy

J'utilise les réflexions dans l'implémentation toString () de ma classe de préférences pour voir les membres et les valeurs de la classe (débogage simple et rapide).

Le code simplifié que j'utilise:

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();

    Class<?> thisClass = null;
    try {
        thisClass = Class.forName(this.getClass().getName());

        Field[] aClassFields = thisClass.getDeclaredFields();
        sb.append(this.getClass().getSimpleName() + " [ ");
        for(Field f : aClassFields){
            String fName = f.getName();
            sb.append("(" + f.getType() + ") " + fName + " = " + f.get(this) + ", ");
        }
        sb.append("]");
    } catch (Exception e) {
        e.printStackTrace();
    }

    return sb.toString();
}

J'espère que ça va aider quelqu'un, parce que j'ai aussi fouillé.

17
silversmurf
 Integer typeValue = 0;
 try {
     Class<Types> types = Types.class;
     Java.lang.reflect.Field field = types.getDeclaredField("Type");
     field.setAccessible(true);
     Object value = field.get(types);
     typeValue = (Integer) value;
 } catch (Exception e) {
     e.printStackTrace();
 }
10
Rahul sharma

Bien que ce que vous essayez d’obtenir ne soit pas vraiment clair, j’ai repéré une erreur évidente dans votre code: Field.get() attend l’objet qui contient le champ en tant qu’argument, et non une valeur (possible) de ce champ. Donc, vous devriez avoir field.get(object).

Puisque vous semblez rechercher la valeur du champ, vous pouvez l'obtenir en tant que:

Object objectValue = field.get(object);

Pas besoin d'instancier le type de champ et de créer une valeur vide/par défaut; ou peut-être qu'il y a quelque chose qui m'a manqué.

8
Costi Ciudatu

Vous appelez get avec le mauvais argument.

CA devrait etre:

Object value = field.get(object);
4
Seba