it-swarm.com.de

Privaten Feldwert mit Reflektion festlegen

Ich habe 2 Klassen: Father und Child

public class Father implements Serializable, JSONInterface {

    private String a_field;

    //setter and getter here

}

public class Child extends Father {
    //empty class
}

Mit Reflektion möchte ich a_field in Child class setzen:

Class<?> clazz = Class.forName("Child");
Object cc = clazz.newInstance();

Field f1 = cc.getClass().getField("a_field");
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc.getClass());
System.out.println("field: " + str1);

aber ich habe eine ausnahme:

Ausnahme im Thread "main" Java.lang.NoSuchFieldException: a_field

Aber wenn ich es versuche:

Child child = new Child();
child.setA_field("123");

es klappt.

Mit der Setter-Methode habe ich dasselbe Problem:

method = cc.getClass().getMethod("setA_field");
method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" });
25
user1066183

Um auf ein privates Feld zuzugreifen, müssen Sie Field::setAccessible auf true setzen. Sie können das Feld von der Superklasse abziehen. Dieser Code funktioniert:

Class<?> clazz = Child.class;
Object cc = clazz.newInstance();

Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field");
f1.setAccessible(true);
f1.set(cc, "reflecting on life");
String str1 = (String) f1.get(cc);
System.out.println("field: " + str1);
80
John McClean

Apache commons-lang3 verwenden:

FieldUtils.writeField(childInstance, "a_field", "Hello", true);

Das "wahre" zwingt es, auch bei "privat" zu setzen.

21
David Lavender

Dieses kann auch auf private Felder zugreifen, ohne etwas tun zu müssen

import org.Apache.commons.lang3.reflect.FieldUtils;
Object value = FieldUtils.readField(entity, fieldName, true);
4
Sacky San

Sie können Manifolds@Jailbreak für die direkte, typsichere Java-Reflektion verwenden:

@Jailbreak Child child = new Child();
child.a_field = "123;

@Jailbreak entsperrt die untergeordnete lokale Variable im Compiler für den direkten Zugriff auf alle Mitglieder in der Hierarchie von Child.

Ebenso können Sie die Erweiterungsmethode jailbreak () zur einmaligen Verwendung verwenden:

child.jailbreak().a_field = "123";

Über die jailbreak()-Methode können Sie auf jedes Mitglied in der Hierarchie von Child zugreifen.

In beiden Fällen löst der Compiler den Feldzugriff für Sie typsicher auf, als ob ein öffentliches Feld, während Manifold unter der Haube einen effizienten Reflexionscode für Sie generiert.

Erfahren Sie mehr über Manifold .

0
Scott McKinney