¿Es posible invocar atributos o métodos privados a través de la reflexión?

2 minutos de lectura

Avatar de usuario de MJ
M.J.

Estaba tratando de obtener el valor de un atributo privado estático a través de la reflexión, pero falla con un error.

Class class = home.Student.class;
Field field = studentClass.getDeclaredField("nstance");
Object obj = field.get(null);

La excepción que obtengo es:

java.lang.IllegalAccessException: Class com.test.ReflectionTest can not access a member of class home.Student with modifiers "private static".

Además, hay un privado que debo invocar, con el siguiente código.

Method method = studentClass.getMethod("addMarks");
method.invoke(studentClass.newInstance(), 1);

pero el problema es que la clase Student es una clase singleton y un constructor en privado, y no se puede acceder a ella.

Puede establecer el campo accesible:

field.setAccessible(true);

Avatar de usuario de Aleksi Yrttiaho
Aleksi Yrttiaho

Sí, lo es. Tienes que configurarlos accesibles usando setAccessible(true) definido en AccesibleObject esa es una super clase de ambos Field y Method

Con el campo estático deberías poder hacer:

Class class = home.Student.class;
Field field = studentClass.getDeclaredField("nstance");
field.setAccessible(true); // suppress Java access checking
Object obj = field.get(null); // as the field is a static field  
                              // the instance parameter is ignored 
                              // and may be null. 
field.setAccesible(false); // continue to use Java access checking

Y con el método privado

Method method = studentClass.getMethod("addMarks");
method.setAccessible(true); // exactly the same as with the field
method.invoke(studentClass.newInstance(), 1);

Y con un constructor privado:

Constructor constructor = studentClass.getDeclaredConstructor(param, types);
constructor.setAccessible(true);
constructor.newInstance(param, values);

  • el constructor es privado, y aún podemos invocarlo usando newInstance ¿¿¿método???

    – MJ

    2 de agosto de 2011 a las 12:16

  • hay un pequeño error tipográfico, field.setAccessible(false);

    – Anil

    15 de febrero de 2019 a las 11:30

Avatar de usuario de Bohemian
bohemio

Sí, puedes “hacer trampa” así:

    Field somePrivateField = SomeClass.class.getDeclaredField("somePrivateFieldName");
    somePrivateField.setAccessible(true); // Subvert the declared "private" visibility
    Object fieldValue = somePrivateField.get(someInstance);

¿Ha sido útil esta solución?