J'ai 2 classes: Father
et Child
public class Father implements Serializable, JSONInterface {
private String a_field;
//setter and getter here
}
public class Child extends Father {
//empty class
}
Avec réflexion, je souhaite définir a_field
dans la classe Child
:
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);
mais j'ai une exception:
Exception dans le fil "principal" Java.lang.NoSuchFieldException: a_field
Mais si j'essaye:
Child child = new Child();
child.setA_field("123");
Ça marche.
En utilisant la méthode setter j'ai le même problème:
method = cc.getClass().getMethod("setA_field");
method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" });
Pour accéder à un champ privé, vous devez définir Field::setAccessible
sur true. Vous pouvez retirer le champ de la super classe. Ce code fonctionne:
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);
Utilisation d'Apache commons-lang3:
FieldUtils.writeField(childInstance, "a_field", "Hello", true);
Le "vrai" l'oblige à se mettre, même avec "privé".
Celui-ci peut aussi accéder à des champs privés sans rien faire
import org.Apache.commons.lang3.reflect.FieldUtils;
Object value = FieldUtils.readField(entity, fieldName, true);
Vous pouvez utiliser Manifold@Jailbreak pour une réflexion Java directe et sécurisée au type:
@Jailbreak Child child = new Child();
child.a_field = "123;
@Jailbreak
déverrouille la variable locale enfant dans le compilateur pour un accès direct à tous les membres de la hiérarchie Child
.
De même, vous pouvez utiliser la méthode d'extension jailbreak () pour une utilisation unique:
child.jailbreak().a_field = "123";
Avec la méthode jailbreak()
, vous pouvez accéder à n’importe quel membre de la hiérarchie de Child
.
Dans les deux cas, le compilateur résout l'accès au champ pour vous en toute sécurité, comme s'il s'agissait d'un champ public, tandis que Manifold génère pour vous un code de réflexion efficace.
En savoir plus sur Collecteur .