java reflection field

Java, establecer el valor del campo con la reflexión



reflection field (4)

El método a continuación establece un campo en su objeto incluso si el campo está en una superclase

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

Estoy trabajando con un proyecto que no es opensource y necesito modificar una o más de sus clases.

en una clase es siguiente colección:

private Map<Integer, TTP> ttp = new HashMap<>();

todo lo que necesito hacer es usar la reflexión y usar el mapa de mapa concurrente aquí. He intentado seguir el código pero no funciona.

Field f = ..getClass().getDeclaredField("ttp"); f.setAccessible(true); f.set(null, new ConcurrentHashMap<>());


Espero que esto sea algo que estás tratando de hacer:

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

Se imprime:

value1


Puedes probar esto:

//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...");


Vale la pena leer Oracle Java Tutorial - Obtención y configuración de valores de campo

Field # set (Objeto objeto, valor Objeto) establece el campo representado por este objeto Field en el argumento del objeto especificado en el nuevo valor especificado.

Deberia ser asi

f.set(objectOfTheClass, new ConcurrentHashMap<>());

No puede establecer ningún valor en el objeto null Si se intenta, se generará una NullPointerException

Nota: establecer el valor de un campo a través de la reflexión tiene una cierta cantidad de sobrecarga de rendimiento porque se deben realizar varias operaciones, como validar permisos de acceso. Desde el punto de vista del tiempo de ejecución, los efectos son los mismos y la operación es tan atómica como si el valor se cambiara en el código de clase directamente.