Je travaille avec un projet qui n'est pas opensource et j'ai besoin de modifier une ou plusieurs classes.
Dans une classe est la collection suivante:
private Map<Integer, TTP> ttp = new HashMap<>();
Tout ce que je dois faire, c'est utiliser la réflexion et utiliser concurrenthashmap ici. J'ai essayé de suivre le code mais cela ne fonctionne pas.
Field f = ..getClass().getDeclaredField("ttp");
f.setAccessible(true);
f.set(null, new ConcurrentHashMap<>());
J'espère que c'est quelque chose que vous essayez de faire:
import Java.lang.reflect.Field;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.concurrent.ConcurrentHashMap;
public class Test {
private Map ttp = new HashMap();
public void test() {
Field declaredField = null;
try {
declaredField = Test.class.getDeclaredField("ttp");
boolean accessible = declaredField.isAccessible();
declaredField.setAccessible(true);
ConcurrentHashMap<Object, Object> concHashMap = new ConcurrentHashMap<Object, Object>();
concHashMap.put("key1", "value1");
declaredField.set(this, concHashMap);
Object value = ttp.get("key1");
System.out.println(value);
declaredField.setAccessible(accessible);
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String... args) {
Test test = new Test();
test.test();
}
}
Il imprime:
value1
Cela vaut la peine de le lire Oracle Java Tutoriel - Obtention et définition des valeurs de champ
Field # set (Object object, Object value) définit le champ représenté par cet objet Field
sur l'objet spécifié argument à la nouvelle valeur spécifiée.
Ça devrait être comme ça
f.set(objectOfTheClass, new ConcurrentHashMap<>());
Vous ne pouvez définir aucune valeur dans null
Object Si vous essayez, vous obtiendrez alors NullPointerException
Remarque: La définition de la valeur d'un champ par réflexion a une certaine valeur de surcoût de performance car diverses opérations doivent être effectuées, telles que la validation. autorisations d'accès. Du point de vue de l'exécution, les effets sont les mêmes et l'opération est aussi atomique que si la valeur avait été modifiée directement dans le code de classe.
La méthode ci-dessous définit un champ sur votre objet même s'il est dans une superclasse
/**
* Sets a field value on a given object
*
* @param targetObject the object to set the field value on
* @param fieldName exact name of the field
* @param fieldValue value to set on the field
* @return true if the value was successfully set, false otherwise
*/
public static boolean setField(Object targetObject, String fieldName, Object fieldValue) {
Field field;
try {
field = targetObject.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
field = null;
}
Class superClass = targetObject.getClass().getSuperclass();
while (field == null && superClass != null) {
try {
field = superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
superClass = superClass.getSuperclass();
}
}
if (field == null) {
return false;
}
field.setAccessible(true);
try {
field.set(targetObject, fieldValue);
return true;
} catch (IllegalAccessException e) {
return false;
}
}
Vous pouvez essayer ceci:
//Your class instance
Publication publication = new Publication();
//Get class with full path(with package name)
Class<?> c = Class.forName("com.example.publication.models.Publication");
//Get method
Method method = c.getDeclaredMethod ("setTitle", String.class);
//set value
method.invoke (publication, "Value to want to set here...");