it-swarm.com.de

Reflection generic get field value

Ich versuche, Feldwert über Reflexion zu erhalten. Das Problem ist, dass ich den Feldtyp nicht kenne und es entscheiden muss, während ich den Wert erhalte.

Dieser Code ergibt sich mit dieser Ausnahme:

Das Java.lang.String-Feld com .... fieldName kann nicht auf Java.lang.String gesetzt werden

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

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

Object value = field.get(objectValue);

Ich habe versucht zu casten, aber ich bekomme Kompilierungsfehler:

field.get((targetType)objectValue)

oder

targetType objectValue = targetType.newInstance();

Wie kann ich das machen?

119
Ido Barash

Wie bereits beantwortet, sollten Sie verwenden:

Object value = field.get(objectInstance);

Eine andere Möglichkeit, die manchmal bevorzugt wird, besteht darin, den Getter dynamisch aufzurufen. Beispielcode:

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

Beachten Sie auch, dass Sie das Feld rekursiv bestimmen müssen, wenn Ihre Klasse von einer anderen Klasse erbt. zum Beispiel, um alle Felder einer bestimmten Klasse abzurufen;

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

Sie sollten eine Objekt an Get Methode des Feld übergeben, also

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

Ich verwende die Reflektionen in der toString () -Implementierung meiner Präferenzklasse, um die Klassenmitglieder und -werte anzuzeigen (einfaches und schnelles Debuggen).

Der vereinfachte Code, den ich benutze:

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

Ich hoffe, dass es jemandem hilft, da ich auch gesucht habe.

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

Obwohl mir nicht wirklich klar ist, was Sie erreichen möchten, habe ich einen offensichtlichen Fehler in Ihrem Code entdeckt: Field.get() erwartet das Objekt, das das Feld als Argument enthält, nicht einen (möglichen) Wert dieses Felds . Sie sollten also field.get(object) haben.

Da Sie scheinbar nach dem Feldwert suchen, können Sie diesen erhalten als:

Object objectValue = field.get(object);

Es ist nicht erforderlich, den Feldtyp zu instanziieren und einen Leer-/Standardwert zu erstellen. oder vielleicht habe ich etwas verpasst.

8
Costi Ciudatu

Sie rufen mit dem falschen Argument bekommen.

Es sollte sein:

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